aggas.pas 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962
  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. globtype,globals,
  25. aasmbase,aasmtai,aasmdata,
  26. assemble;
  27. type
  28. TCPUInstrWriter = class;
  29. {# This is a derived class which is used to write
  30. GAS styled assembler.
  31. }
  32. { TGNUAssembler }
  33. TGNUAssembler=class(texternalassembler)
  34. protected
  35. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;virtual;
  36. function sectionattrs_coff(atype:TAsmSectiontype):string;virtual;
  37. function sectionalignment_aix(atype:TAsmSectiontype;secalign: byte):string;
  38. procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:byte);
  39. procedure WriteExtraHeader;virtual;
  40. procedure WriteExtraFooter;virtual;
  41. procedure WriteInstruction(hp: tai);
  42. procedure WriteWeakSymbolDef(s: tasmsymbol); virtual;
  43. procedure WriteAixStringConst(hp: tai_string);
  44. procedure WriteAixIntConst(hp: tai_const);
  45. procedure WriteUnalignedIntConst(hp: tai_const);
  46. procedure WriteDirectiveName(dir: TAsmDirective); virtual;
  47. public
  48. function MakeCmdLine: TCmdStr; override;
  49. procedure WriteTree(p:TAsmList);override;
  50. procedure WriteAsmList;override;
  51. destructor destroy; override;
  52. private
  53. setcount: longint;
  54. procedure WriteDecodedSleb128(a: int64);
  55. procedure WriteDecodedUleb128(a: qword);
  56. function NextSetLabel: string;
  57. protected
  58. InstrWriter: TCPUInstrWriter;
  59. end;
  60. {# This is the base class for writing instructions.
  61. The WriteInstruction() method must be overridden
  62. to write a single instruction to the assembler
  63. file.
  64. }
  65. TCPUInstrWriter = class
  66. constructor create(_owner: TGNUAssembler);
  67. procedure WriteInstruction(hp : tai); virtual; abstract;
  68. protected
  69. owner: TGNUAssembler;
  70. end;
  71. { TAppleGNUAssembler }
  72. TAppleGNUAssembler=class(TGNUAssembler)
  73. protected
  74. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  75. procedure WriteWeakSymbolDef(s: tasmsymbol); override;
  76. end;
  77. TAoutGNUAssembler=class(TGNUAssembler)
  78. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  79. end;
  80. implementation
  81. uses
  82. SysUtils,
  83. cutils,cfileutl,systems,
  84. fmodule,verbose,
  85. {$ifdef TEST_WIN64_SEH}
  86. itcpugas,
  87. {$endif TEST_WIN64_SEH}
  88. cpubase;
  89. const
  90. line_length = 70;
  91. var
  92. symendcount : longint;
  93. type
  94. {$ifdef cpuextended}
  95. t80bitarray = array[0..9] of byte;
  96. {$endif cpuextended}
  97. t64bitarray = array[0..7] of byte;
  98. t32bitarray = array[0..3] of byte;
  99. {****************************************************************************}
  100. { Support routines }
  101. {****************************************************************************}
  102. function single2str(d : single) : string;
  103. var
  104. hs : string;
  105. begin
  106. str(d,hs);
  107. { replace space with + }
  108. if hs[1]=' ' then
  109. hs[1]:='+';
  110. single2str:='0d'+hs
  111. end;
  112. function double2str(d : double) : 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. double2str:='0d'+hs
  121. end;
  122. function extended2str(e : extended) : string;
  123. var
  124. hs : string;
  125. begin
  126. str(e,hs);
  127. { replace space with + }
  128. if hs[1]=' ' then
  129. hs[1]:='+';
  130. extended2str:='0d'+hs
  131. end;
  132. { convert floating point values }
  133. { to correct endian }
  134. procedure swap64bitarray(var t: t64bitarray);
  135. var
  136. b: byte;
  137. begin
  138. b:= t[7];
  139. t[7] := t[0];
  140. t[0] := b;
  141. b := t[6];
  142. t[6] := t[1];
  143. t[1] := b;
  144. b:= t[5];
  145. t[5] := t[2];
  146. t[2] := b;
  147. b:= t[4];
  148. t[4] := t[3];
  149. t[3] := b;
  150. end;
  151. procedure swap32bitarray(var t: t32bitarray);
  152. var
  153. b: byte;
  154. begin
  155. b:= t[1];
  156. t[1]:= t[2];
  157. t[2]:= b;
  158. b:= t[0];
  159. t[0]:= t[3];
  160. t[3]:= b;
  161. end;
  162. const
  163. ait_const2str : array[aitconst_128bit..aitconst_64bit_unaligned] of string[20]=(
  164. #9'.fixme128'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9,#9'.byte'#9,
  165. #9'.sleb128'#9,#9'.uleb128'#9,
  166. #9'.rva'#9,#9'.secrel32'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9,
  167. #9'.short'#9,#9'.long'#9,#9'.quad'#9
  168. );
  169. ait_unaligned_consts = [aitconst_16bit_unaligned..aitconst_64bit_unaligned];
  170. { Sparc type of unaligned pseudo-instructions }
  171. use_ua_sparc_systems = [system_sparc_linux];
  172. ait_ua_sparc_const2str : array[aitconst_16bit_unaligned..aitconst_64bit_unaligned]
  173. of string[20]=(
  174. #9'.uahalf'#9,#9'.uaword'#9,#9'.uaxword'#9
  175. );
  176. { Alpha type of unaligned pseudo-instructions }
  177. use_ua_alpha_systems = [system_alpha_linux];
  178. ait_ua_alpha_const2str : array[aitconst_16bit_unaligned..aitconst_64bit_unaligned]
  179. of string[20]=(
  180. #9'.uword'#9,#9'.ulong'#9,#9'.uquad'#9
  181. );
  182. { Generic unaligned pseudo-instructions, seems ELF specific }
  183. use_ua_elf_systems = [system_mipsel_linux,system_mipseb_linux];
  184. ait_ua_elf_const2str : array[aitconst_16bit_unaligned..aitconst_64bit_unaligned]
  185. of string[20]=(
  186. #9'.2byte'#9,#9'.4byte'#9,#9'.8byte'#9
  187. );
  188. {****************************************************************************}
  189. { GNU Assembler writer }
  190. {****************************************************************************}
  191. destructor TGNUAssembler.Destroy;
  192. begin
  193. InstrWriter.free;
  194. inherited destroy;
  195. end;
  196. function TGNUAssembler.MakeCmdLine: TCmdStr;
  197. begin
  198. result := inherited MakeCmdLine;
  199. // MWE: disabled again. It generates dwarf info for the generated .s
  200. // files as well. This conflicts with the info we generate
  201. // if target_dbg.id = dbg_dwarf then
  202. // result := result + ' --gdwarf-2';
  203. end;
  204. function TGNUAssembler.NextSetLabel: string;
  205. begin
  206. inc(setcount);
  207. result := target_asm.labelprefix+'$set$'+tostr(setcount);
  208. end;
  209. function is_smart_section(atype:TAsmSectiontype):boolean;
  210. begin
  211. { For bss we need to set some flags that are target dependent,
  212. it is easier to disable it for smartlinking. It doesn't take up
  213. filespace }
  214. result:=not(target_info.system in systems_darwin) and
  215. create_smartlink_sections and
  216. (atype<>sec_toc) and
  217. (atype<>sec_user) and
  218. { on embedded systems every byte counts, so smartlink bss too }
  219. ((atype<>sec_bss) or (target_info.system in systems_embedded));
  220. end;
  221. function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  222. const
  223. secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
  224. '.text',
  225. '.data',
  226. { why doesn't .rodata work? (FK) }
  227. { sometimes we have to create a data.rel.ro instead of .rodata, e.g. for }
  228. { vtables (and anything else containing relocations), otherwise those are }
  229. { not relocated properly on e.g. linux/ppc64. g++ generates there for a }
  230. { vtable for a class called Window: }
  231. { .section .data.rel.ro._ZTV6Window,"awG",@progbits,_ZTV6Window,comdat }
  232. { TODO: .data.ro not yet working}
  233. {$if defined(arm) or defined(powerpc)}
  234. '.rodata',
  235. {$else arm}
  236. '.data',
  237. {$endif arm}
  238. {$if defined(m68k)} { Amiga/m68k GNU AS doesn't seem to like .rodata (KB) }
  239. '.data',
  240. {$else}
  241. '.rodata',
  242. {$endif}
  243. '.bss',
  244. '.threadvar',
  245. '.pdata',
  246. '', { stubs }
  247. '__DATA,__nl_symbol_ptr',
  248. '__DATA,__la_symbol_ptr',
  249. '__DATA,__mod_init_func',
  250. '__DATA,__mod_term_func',
  251. '.stab',
  252. '.stabstr',
  253. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  254. '.eh_frame',
  255. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  256. '.fpc',
  257. '.toc',
  258. '.init',
  259. '.fini',
  260. '.objc_class',
  261. '.objc_meta_class',
  262. '.objc_cat_cls_meth',
  263. '.objc_cat_inst_meth',
  264. '.objc_protocol',
  265. '.objc_string_object',
  266. '.objc_cls_meth',
  267. '.objc_inst_meth',
  268. '.objc_cls_refs',
  269. '.objc_message_refs',
  270. '.objc_symbols',
  271. '.objc_category',
  272. '.objc_class_vars',
  273. '.objc_instance_vars',
  274. '.objc_module_info',
  275. '.objc_class_names',
  276. '.objc_meth_var_types',
  277. '.objc_meth_var_names',
  278. '.objc_selector_strs',
  279. '.objc_protocol_ext',
  280. '.objc_class_ext',
  281. '.objc_property',
  282. '.objc_image_info',
  283. '.objc_cstring_object',
  284. '.objc_sel_fixup',
  285. '__DATA,__objc_data',
  286. '__DATA,__objc_const',
  287. '.objc_superrefs',
  288. '__DATA, __datacoal_nt,coalesced',
  289. '.objc_classlist',
  290. '.objc_nlclasslist',
  291. '.objc_catlist',
  292. '.obcj_nlcatlist',
  293. '.objc_protolist'
  294. );
  295. secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
  296. '.text',
  297. '.data.rel',
  298. '.data.rel',
  299. '.data.rel',
  300. '.bss',
  301. '.threadvar',
  302. '.pdata',
  303. '', { stubs }
  304. '__DATA,__nl_symbol_ptr',
  305. '__DATA,__la_symbol_ptr',
  306. '__DATA,__mod_init_func',
  307. '__DATA,__mod_term_func',
  308. '.stab',
  309. '.stabstr',
  310. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  311. '.eh_frame',
  312. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  313. '.fpc',
  314. '.toc',
  315. '.init',
  316. '.fini',
  317. '.objc_class',
  318. '.objc_meta_class',
  319. '.objc_cat_cls_meth',
  320. '.objc_cat_inst_meth',
  321. '.objc_protocol',
  322. '.objc_string_object',
  323. '.objc_cls_meth',
  324. '.objc_inst_meth',
  325. '.objc_cls_refs',
  326. '.objc_message_refs',
  327. '.objc_symbols',
  328. '.objc_category',
  329. '.objc_class_vars',
  330. '.objc_instance_vars',
  331. '.objc_module_info',
  332. '.objc_class_names',
  333. '.objc_meth_var_types',
  334. '.objc_meth_var_names',
  335. '.objc_selector_strs',
  336. '.objc_protocol_ext',
  337. '.objc_class_ext',
  338. '.objc_property',
  339. '.objc_image_info',
  340. '.objc_cstring_object',
  341. '.objc_sel_fixup',
  342. '__DATA, __objc_data',
  343. '__DATA, __objc_const',
  344. '.objc_superrefs',
  345. '__DATA, __datacoal_nt,coalesced',
  346. '.objc_classlist',
  347. '.objc_nlclasslist',
  348. '.objc_catlist',
  349. '.obcj_nlcatlist',
  350. '.objc_protolist'
  351. );
  352. var
  353. sep : string[3];
  354. secname : string;
  355. begin
  356. if (cs_create_pic in current_settings.moduleswitches) and
  357. not(target_info.system in systems_darwin) then
  358. secname:=secnames_pic[atype]
  359. else
  360. secname:=secnames[atype];
  361. {$ifdef m68k}
  362. { old Amiga GNU AS doesn't support .section .fpc }
  363. if (atype=sec_fpc) and (target_info.system = system_m68k_amiga) then
  364. secname:=secnames[sec_data];
  365. {$endif}
  366. if (atype=sec_fpc) and (Copy(aname,1,3)='res') then
  367. begin
  368. result:=secname+'.'+aname;
  369. exit;
  370. end;
  371. if (atype=sec_threadvar) and
  372. (target_info.system in (systems_windows+systems_wince)) then
  373. secname:='.tls';
  374. { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
  375. Thus, data which normally goes into .rodata and .rodata_norel sections must
  376. end up in .data section }
  377. if (atype in [sec_rodata,sec_rodata_norel]) and
  378. (target_info.system=system_i386_go32v2) then
  379. secname:='.data';
  380. { section type user gives the user full controll on the section name }
  381. if atype=sec_user then
  382. secname:=aname;
  383. if is_smart_section(atype) and (aname<>'') then
  384. begin
  385. case aorder of
  386. secorder_begin :
  387. sep:='.b_';
  388. secorder_end :
  389. sep:='.z_';
  390. else
  391. sep:='.n_';
  392. end;
  393. result:=secname+sep+aname
  394. end
  395. else
  396. result:=secname;
  397. end;
  398. function TGNUAssembler.sectionattrs_coff(atype:TAsmSectiontype):string;
  399. begin
  400. case atype of
  401. sec_code, sec_init, sec_fini, sec_stub:
  402. result:='x';
  403. { TODO: must be individual for each section }
  404. sec_user:
  405. result:='d';
  406. sec_data, sec_data_lazy, sec_data_nonlazy, sec_fpc,
  407. sec_idata2, sec_idata4, sec_idata5, sec_idata6, sec_idata7:
  408. result:='d';
  409. { TODO: these need a fix to become read-only }
  410. sec_rodata, sec_rodata_norel:
  411. result:='d';
  412. sec_bss:
  413. result:='b';
  414. { TODO: Somewhat questionable. FPC does not allow initialized threadvars,
  415. so no sense to mark it as containing data. But Windows allows it to
  416. contain data, and Linux even has .tdata and .tbss }
  417. sec_threadvar:
  418. result:='b';
  419. sec_pdata, sec_edata, sec_eh_frame, sec_toc:
  420. result:='r';
  421. sec_stab,sec_stabstr,
  422. sec_debug_frame,sec_debug_info,sec_debug_line,sec_debug_abbrev:
  423. result:='n';
  424. else
  425. result:=''; { defaults to data+load }
  426. end;
  427. end;
  428. function TGNUAssembler.sectionalignment_aix(atype:TAsmSectiontype;secalign: byte): string;
  429. var
  430. l: longint;
  431. begin
  432. if (secalign=0) or
  433. not(atype in [sec_code,sec_bss,sec_rodata_norel,sec_rodata,sec_data]) then
  434. begin
  435. result:='';
  436. exit;
  437. end;
  438. if not ispowerof2(secalign,l) then
  439. internalerror(2012022201);
  440. result:=tostr(l);
  441. end;
  442. procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:byte);
  443. var
  444. s : string;
  445. begin
  446. AsmLn;
  447. case target_info.system of
  448. system_i386_OS2,
  449. system_i386_EMX,
  450. system_m68k_amiga, { amiga has old GNU AS (2.14), which blews up from .section (KB) }
  451. system_m68k_linux: ;
  452. system_powerpc_darwin,
  453. system_i386_darwin,
  454. system_i386_iphonesim,
  455. system_powerpc64_darwin,
  456. system_x86_64_darwin,
  457. system_arm_darwin,
  458. system_powerpc_aix,
  459. system_powerpc64_aix:
  460. begin
  461. if (atype in [sec_stub,sec_objc_data,sec_objc_const,sec_data_coalesced]) then
  462. AsmWrite('.section ');
  463. end
  464. else
  465. AsmWrite('.section ');
  466. end;
  467. s:=sectionname(atype,aname,aorder);
  468. AsmWrite(s);
  469. case atype of
  470. sec_fpc :
  471. if aname = 'resptrs' then
  472. AsmWrite(', "a", @progbits');
  473. sec_stub :
  474. begin
  475. case target_info.system of
  476. { there are processor-independent shortcuts available }
  477. { for this, namely .symbol_stub and .picsymbol_stub, but }
  478. { they don't work and gcc doesn't use them either... }
  479. system_powerpc_darwin,
  480. system_powerpc64_darwin:
  481. if (cs_create_pic in current_settings.moduleswitches) then
  482. AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
  483. else
  484. AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
  485. system_i386_darwin,
  486. system_i386_iphonesim:
  487. AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
  488. system_arm_darwin:
  489. if (cs_create_pic in current_settings.moduleswitches) then
  490. AsmWriteln('__TEXT,__picsymbolstub4,symbol_stubs,none,16')
  491. else
  492. AsmWriteln('__TEXT,__symbol_stub4,symbol_stubs,none,12')
  493. { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs }
  494. else
  495. internalerror(2006031101);
  496. end;
  497. end;
  498. else
  499. { GNU AS won't recognize '.text.n_something' section name as belonging
  500. to '.text' and assigns default attributes to it, which is not
  501. always correct. We have to fix it.
  502. TODO: This likely applies to all systems which smartlink without
  503. creating libraries }
  504. if (target_info.system in [system_i386_win32,system_x86_64_win64]) and
  505. is_smart_section(atype) and (aname<>'') then
  506. begin
  507. s:=sectionattrs_coff(atype);
  508. if (s<>'') then
  509. AsmWrite(',"'+s+'"');
  510. end
  511. else if target_info.system in systems_aix then
  512. begin
  513. s:=sectionalignment_aix(atype,secalign);
  514. if s<>'' then
  515. AsmWrite(','+s);
  516. end;
  517. end;
  518. AsmLn;
  519. LastSecType:=atype;
  520. end;
  521. procedure TGNUAssembler.WriteDecodedUleb128(a: qword);
  522. var
  523. i,len : longint;
  524. buf : array[0..63] of byte;
  525. begin
  526. len:=EncodeUleb128(a,buf);
  527. for i:=0 to len-1 do
  528. begin
  529. if (i > 0) then
  530. AsmWrite(',');
  531. AsmWrite(tostr(buf[i]));
  532. end;
  533. end;
  534. procedure TGNUAssembler.WriteDecodedSleb128(a: int64);
  535. var
  536. i,len : longint;
  537. buf : array[0..255] of byte;
  538. begin
  539. len:=EncodeSleb128(a,buf);
  540. for i:=0 to len-1 do
  541. begin
  542. if (i > 0) then
  543. AsmWrite(',');
  544. AsmWrite(tostr(buf[i]));
  545. end;
  546. end;
  547. procedure TGNUAssembler.WriteTree(p:TAsmList);
  548. function needsObject(hp : tai_symbol) : boolean;
  549. begin
  550. needsObject :=
  551. (
  552. assigned(hp.next) and
  553. (tai(hp.next).typ in [ait_const,ait_datablock,
  554. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit])
  555. ) or
  556. (hp.sym.typ=AT_DATA);
  557. end;
  558. procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint);
  559. var
  560. i: longint;
  561. begin
  562. last_align:=alignment;
  563. if alignment>1 then
  564. begin
  565. if not(target_info.system in (systems_darwin+systems_aix)) then
  566. begin
  567. AsmWrite(#9'.balign '+tostr(alignment));
  568. if use_op then
  569. AsmWrite(','+tostr(fillop))
  570. {$ifdef x86}
  571. { force NOP as alignment op code }
  572. else if LastSecType=sec_code then
  573. AsmWrite(',0x90');
  574. {$endif x86}
  575. end
  576. else
  577. begin
  578. { darwin and aix as only support .align }
  579. if not ispowerof2(alignment,i) then
  580. internalerror(2003010305);
  581. AsmWrite(#9'.align '+tostr(i));
  582. last_align:=i;
  583. end;
  584. AsmLn;
  585. end;
  586. end;
  587. var
  588. ch : char;
  589. hp : tai;
  590. constdef : taiconst_type;
  591. s,t : string;
  592. i,pos,l : longint;
  593. InlineLevel : cardinal;
  594. last_align : longint;
  595. co : comp;
  596. sin : single;
  597. d : double;
  598. {$ifdef cpuextended}
  599. e : extended;
  600. {$endif cpuextended}
  601. do_line : boolean;
  602. sepChar : char;
  603. replaceforbidden: boolean;
  604. begin
  605. if not assigned(p) then
  606. exit;
  607. replaceforbidden:=target_asm.dollarsign<>'$';
  608. last_align := 2;
  609. InlineLevel:=0;
  610. { lineinfo is only needed for al_procedures (PFV) }
  611. do_line:=(cs_asm_source in current_settings.globalswitches) or
  612. ((cs_lineinfo in current_settings.moduleswitches)
  613. and (p=current_asmdata.asmlists[al_procedures]));
  614. hp:=tai(p.first);
  615. while assigned(hp) do
  616. begin
  617. prefetch(pointer(hp.next)^);
  618. if not(hp.typ in SkipLineInfo) then
  619. begin
  620. current_filepos:=tailineinfo(hp).fileinfo;
  621. { no line info for inlined code }
  622. if do_line and (inlinelevel=0) then
  623. WriteSourceLine(hp as tailineinfo);
  624. end;
  625. case hp.typ of
  626. ait_comment :
  627. Begin
  628. AsmWrite(target_asm.comment);
  629. AsmWritePChar(tai_comment(hp).str);
  630. AsmLn;
  631. End;
  632. ait_regalloc :
  633. begin
  634. if (cs_asm_regalloc in current_settings.globalswitches) then
  635. begin
  636. AsmWrite(#9+target_asm.comment+'Register ');
  637. repeat
  638. AsmWrite(std_regname(Tai_regalloc(hp).reg));
  639. if (hp.next=nil) or
  640. (tai(hp.next).typ<>ait_regalloc) or
  641. (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
  642. break;
  643. hp:=tai(hp.next);
  644. AsmWrite(',');
  645. until false;
  646. AsmWrite(' ');
  647. AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
  648. end;
  649. end;
  650. ait_tempalloc :
  651. begin
  652. if (cs_asm_tempalloc in current_settings.globalswitches) then
  653. WriteTempalloc(tai_tempalloc(hp));
  654. end;
  655. ait_align :
  656. begin
  657. doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align);
  658. end;
  659. ait_section :
  660. begin
  661. if tai_section(hp).sectype<>sec_none then
  662. if replaceforbidden then
  663. WriteSection(tai_section(hp).sectype,ReplaceForbiddenAsmSymbolChars(tai_section(hp).name^),tai_section(hp).secorder,tai_section(hp).secalign)
  664. else
  665. WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder,tai_section(hp).secalign)
  666. else
  667. begin
  668. {$ifdef EXTDEBUG}
  669. AsmWrite(target_asm.comment);
  670. AsmWriteln(' sec_none');
  671. {$endif EXTDEBUG}
  672. end;
  673. end;
  674. ait_datablock :
  675. begin
  676. if (target_info.system in systems_darwin) then
  677. begin
  678. { On Mac OS X you can't have common symbols in a shared library
  679. since those are in the TEXT section and the text section is
  680. read-only in shared libraries (so it can be shared among different
  681. processes). The alternate code creates some kind of common symbols
  682. in the data segment.
  683. }
  684. if tai_datablock(hp).is_global then
  685. begin
  686. asmwrite('.globl ');
  687. asmwriteln(tai_datablock(hp).sym.name);
  688. asmwriteln('.data');
  689. asmwrite('.zerofill __DATA, __common, ');
  690. asmwrite(tai_datablock(hp).sym.name);
  691. asmwriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
  692. if not(LastSecType in [sec_data,sec_none]) then
  693. writesection(LastSecType,'',secorder_default,1 shl last_align);
  694. end
  695. else
  696. begin
  697. asmwrite(#9'.lcomm'#9);
  698. asmwrite(tai_datablock(hp).sym.name);
  699. asmwrite(','+tostr(tai_datablock(hp).size));
  700. asmwrite(','+tostr(last_align));
  701. asmln;
  702. end;
  703. end
  704. else if target_info.system in systems_aix then
  705. begin
  706. if tai_datablock(hp).is_global then
  707. begin
  708. asmwrite(#9'.globl ');
  709. asmwriteln(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  710. asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  711. asmwriteln(':');
  712. asmwrite(#9'.space ');
  713. asmwriteln(tostr(tai_datablock(hp).size));
  714. if not(LastSecType in [sec_data,sec_none]) then
  715. writesection(LastSecType,'',secorder_default,1 shl last_align);
  716. end
  717. else
  718. begin
  719. asmwrite(#9'.lcomm ');
  720. asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  721. asmwrite(',_data.bss_[RW],');
  722. asmwrite(tostr(tai_datablock(hp).size)+',');
  723. asmwriteln(tostr(last_align));
  724. end;
  725. end
  726. else
  727. begin
  728. {$ifdef USE_COMM_IN_BSS}
  729. if writingpackages then
  730. begin
  731. { The .comm is required for COMMON symbols. These are used
  732. in the shared library loading. All the symbols declared in
  733. the .so file need to resolve to the data allocated in the main
  734. program (PFV) }
  735. if tai_datablock(hp).is_global then
  736. begin
  737. asmwrite(#9'.comm'#9);
  738. if replaceforbidden then
  739. asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name))
  740. else
  741. asmwrite(tai_datablock(hp).sym.name);
  742. asmwrite(','+tostr(tai_datablock(hp).size));
  743. asmwrite(','+tostr(last_align));
  744. asmln;
  745. end
  746. else
  747. begin
  748. asmwrite(#9'.lcomm'#9);
  749. if replaceforbidden then
  750. asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  751. else
  752. asmwrite(tai_datablock(hp).sym.name);
  753. asmwrite(','+tostr(tai_datablock(hp).size));
  754. asmwrite(','+tostr(last_align));
  755. asmln;
  756. end
  757. end
  758. else
  759. {$endif USE_COMM_IN_BSS}
  760. begin
  761. if Tai_datablock(hp).is_global then
  762. begin
  763. asmwrite(#9'.globl ');
  764. if replaceforbidden then
  765. asmwriteln(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
  766. else
  767. asmwriteln(Tai_datablock(hp).sym.name);
  768. end;
  769. if (target_info.system <> system_arm_linux) then
  770. sepChar := '@'
  771. else
  772. sepChar := '%';
  773. if replaceforbidden then
  774. begin
  775. if (tf_needs_symbol_type in target_info.flags) then
  776. asmwriteln(#9'.type '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+sepChar+'object');
  777. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  778. asmwriteln(#9'.size '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+tostr(Tai_datablock(hp).size));
  779. asmwrite(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
  780. end
  781. else
  782. begin
  783. if (tf_needs_symbol_type in target_info.flags) then
  784. asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  785. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  786. asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  787. asmwrite(Tai_datablock(hp).sym.name);
  788. end;
  789. asmwriteln(':');
  790. asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  791. end;
  792. end;
  793. end;
  794. ait_const:
  795. begin
  796. constdef:=tai_const(hp).consttype;
  797. case constdef of
  798. {$ifndef cpu64bitaddr}
  799. aitconst_128bit :
  800. begin
  801. internalerror(200404291);
  802. end;
  803. aitconst_64bit :
  804. begin
  805. if assigned(tai_const(hp).sym) then
  806. internalerror(200404292);
  807. if not(target_info.system in systems_aix) then
  808. begin
  809. AsmWrite(ait_const2str[aitconst_32bit]);
  810. if target_info.endian = endian_little then
  811. begin
  812. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  813. AsmWrite(',');
  814. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  815. end
  816. else
  817. begin
  818. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  819. AsmWrite(',');
  820. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  821. end;
  822. end
  823. else
  824. WriteAixIntConst(tai_const(hp));
  825. AsmLn;
  826. end;
  827. {$endif cpu64bitaddr}
  828. aitconst_uleb128bit,
  829. aitconst_sleb128bit,
  830. {$ifdef cpu64bitaddr}
  831. aitconst_128bit,
  832. aitconst_64bit,
  833. {$endif cpu64bitaddr}
  834. aitconst_32bit,
  835. aitconst_16bit,
  836. aitconst_8bit,
  837. aitconst_rva_symbol,
  838. aitconst_secrel32_symbol,
  839. aitconst_darwin_dwarf_delta32,
  840. aitconst_darwin_dwarf_delta64,
  841. aitconst_half16bit,
  842. aitconst_16bit_unaligned,
  843. aitconst_32bit_unaligned,
  844. aitconst_64bit_unaligned:
  845. begin
  846. { the AIX assembler (and for compatibility, the GNU
  847. assembler when targeting AIX) automatically aligns
  848. .short/.long/.llong to a multiple of 2/4/8 bytes. We
  849. don't want that, since this may be data inside a packed
  850. record -> use .vbyte instead (byte stream of fixed
  851. length) }
  852. if (target_info.system in systems_aix) and
  853. (constdef in [aitconst_128bit,aitconst_64bit,aitconst_32bit,aitconst_16bit]) and
  854. not assigned(tai_const(hp).sym) then
  855. begin
  856. WriteAixIntConst(tai_const(hp));
  857. end
  858. else if (target_info.system in systems_darwin) and
  859. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  860. begin
  861. AsmWrite(ait_const2str[aitconst_8bit]);
  862. case tai_const(hp).consttype of
  863. aitconst_uleb128bit:
  864. WriteDecodedUleb128(qword(tai_const(hp).value));
  865. aitconst_sleb128bit:
  866. WriteDecodedSleb128(int64(tai_const(hp).value));
  867. end
  868. end
  869. else
  870. begin
  871. if (constdef in ait_unaligned_consts) and
  872. (target_info.system in use_ua_sparc_systems) then
  873. AsmWrite(ait_ua_sparc_const2str[constdef])
  874. else if (constdef in ait_unaligned_consts) and
  875. (target_info.system in use_ua_alpha_systems) then
  876. AsmWrite(ait_ua_alpha_const2str[constdef])
  877. else if (constdef in ait_unaligned_consts) and
  878. (target_info.system in use_ua_elf_systems) then
  879. AsmWrite(ait_ua_elf_const2str[constdef])
  880. else if not(target_info.system in systems_aix) or
  881. (constdef<>aitconst_64bit) then
  882. AsmWrite(ait_const2str[constdef])
  883. else
  884. { can't use .llong, because that forces 8 byte
  885. alignnment and we sometimes store addresses on
  886. 4-byte aligned addresses (e.g. in the RTTI) }
  887. AsmWrite('.vbyte'#9'8,');
  888. l:=0;
  889. t := '';
  890. repeat
  891. if assigned(tai_const(hp).sym) then
  892. begin
  893. if assigned(tai_const(hp).endsym) then
  894. begin
  895. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  896. begin
  897. s := NextSetLabel;
  898. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  899. end
  900. else
  901. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  902. end
  903. else
  904. s:=tai_const(hp).sym.name;
  905. if replaceforbidden then
  906. s:=ReplaceForbiddenAsmSymbolChars(s);
  907. if tai_const(hp).value<>0 then
  908. s:=s+tostr_with_plus(tai_const(hp).value);
  909. end
  910. else
  911. {$ifdef cpu64bitaddr}
  912. s:=tostr(tai_const(hp).value);
  913. {$else cpu64bitaddr}
  914. { 64 bit constants are already handled above in this case }
  915. s:=tostr(longint(tai_const(hp).value));
  916. {$endif cpu64bitaddr}
  917. if constdef = aitconst_half16bit then
  918. s:='('+s+')/2';
  919. AsmWrite(s);
  920. inc(l,length(s));
  921. { Values with symbols are written on a single line to improve
  922. reading of the .s file (PFV) }
  923. if assigned(tai_const(hp).sym) or
  924. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  925. (l>line_length) or
  926. (hp.next=nil) or
  927. (tai(hp.next).typ<>ait_const) or
  928. (tai_const(hp.next).consttype<>constdef) or
  929. assigned(tai_const(hp.next).sym) then
  930. break;
  931. hp:=tai(hp.next);
  932. AsmWrite(',');
  933. until false;
  934. if (t <> '') then
  935. begin
  936. AsmLn;
  937. AsmWrite(t);
  938. end;
  939. end;
  940. AsmLn;
  941. end;
  942. else
  943. internalerror(200704251);
  944. end;
  945. end;
  946. { the "and defined(FPC_HAS_TYPE_EXTENDED)" isn't optimal but currently the only solution
  947. it prevents proper cross compilation to i386 though
  948. }
  949. {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
  950. ait_real_80bit :
  951. begin
  952. if do_line then
  953. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_real_80bit(hp).value));
  954. { Make sure e is a extended type, bestreal could be
  955. a different type (bestreal) !! (PFV) }
  956. e:=tai_real_80bit(hp).value;
  957. AsmWrite(#9'.byte'#9);
  958. for i:=0 to 9 do
  959. begin
  960. if i<>0 then
  961. AsmWrite(',');
  962. AsmWrite(tostr(t80bitarray(e)[i]));
  963. end;
  964. for i:=11 to tai_real_80bit(hp).savesize do
  965. AsmWrite(',0');
  966. AsmLn;
  967. end;
  968. {$endif cpuextended}
  969. ait_real_64bit :
  970. begin
  971. if do_line then
  972. AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
  973. d:=tai_real_64bit(hp).value;
  974. { swap the values to correct endian if required }
  975. if source_info.endian <> target_info.endian then
  976. swap64bitarray(t64bitarray(d));
  977. AsmWrite(#9'.byte'#9);
  978. {$ifdef arm}
  979. if tai_real_64bit(hp).formatoptions=fo_hiloswapped then
  980. begin
  981. for i:=4 to 7 do
  982. begin
  983. if i<>4 then
  984. AsmWrite(',');
  985. AsmWrite(tostr(t64bitarray(d)[i]));
  986. end;
  987. for i:=0 to 3 do
  988. begin
  989. AsmWrite(',');
  990. AsmWrite(tostr(t64bitarray(d)[i]));
  991. end;
  992. end
  993. else
  994. {$endif arm}
  995. begin
  996. for i:=0 to 7 do
  997. begin
  998. if i<>0 then
  999. AsmWrite(',');
  1000. AsmWrite(tostr(t64bitarray(d)[i]));
  1001. end;
  1002. end;
  1003. AsmLn;
  1004. end;
  1005. ait_real_32bit :
  1006. begin
  1007. if do_line then
  1008. AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
  1009. sin:=tai_real_32bit(hp).value;
  1010. { swap the values to correct endian if required }
  1011. if source_info.endian <> target_info.endian then
  1012. swap32bitarray(t32bitarray(sin));
  1013. AsmWrite(#9'.byte'#9);
  1014. for i:=0 to 3 do
  1015. begin
  1016. if i<>0 then
  1017. AsmWrite(',');
  1018. AsmWrite(tostr(t32bitarray(sin)[i]));
  1019. end;
  1020. AsmLn;
  1021. end;
  1022. ait_comp_64bit :
  1023. begin
  1024. if do_line then
  1025. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_comp_64bit(hp).value));
  1026. AsmWrite(#9'.byte'#9);
  1027. co:=comp(tai_comp_64bit(hp).value);
  1028. { swap the values to correct endian if required }
  1029. if source_info.endian <> target_info.endian then
  1030. swap64bitarray(t64bitarray(co));
  1031. for i:=0 to 7 do
  1032. begin
  1033. if i<>0 then
  1034. AsmWrite(',');
  1035. AsmWrite(tostr(t64bitarray(co)[i]));
  1036. end;
  1037. AsmLn;
  1038. end;
  1039. ait_string :
  1040. begin
  1041. pos:=0;
  1042. if not(target_info.system in systems_aix) then
  1043. begin
  1044. for i:=1 to tai_string(hp).len do
  1045. begin
  1046. if pos=0 then
  1047. begin
  1048. AsmWrite(#9'.ascii'#9'"');
  1049. pos:=20;
  1050. end;
  1051. ch:=tai_string(hp).str[i-1];
  1052. case ch of
  1053. #0, {This can't be done by range, because a bug in FPC}
  1054. #1..#31,
  1055. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  1056. '"' : s:='\"';
  1057. '\' : s:='\\';
  1058. else
  1059. s:=ch;
  1060. end;
  1061. AsmWrite(s);
  1062. inc(pos,length(s));
  1063. if (pos>line_length) or (i=tai_string(hp).len) then
  1064. begin
  1065. AsmWriteLn('"');
  1066. pos:=0;
  1067. end;
  1068. end;
  1069. end
  1070. else
  1071. WriteAixStringConst(tai_string(hp));
  1072. end;
  1073. ait_label :
  1074. begin
  1075. if (tai_label(hp).labsym.is_used) then
  1076. begin
  1077. if (tai_label(hp).labsym.bind=AB_PRIVATE_EXTERN) then
  1078. begin
  1079. AsmWrite(#9'.private_extern ');
  1080. AsmWriteln(tai_label(hp).labsym.name);
  1081. end;
  1082. if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
  1083. begin
  1084. AsmWrite('.globl'#9);
  1085. if replaceforbidden then
  1086. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
  1087. else
  1088. AsmWriteLn(tai_label(hp).labsym.name);
  1089. end;
  1090. if replaceforbidden then
  1091. AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
  1092. else
  1093. AsmWrite(tai_label(hp).labsym.name);
  1094. AsmWriteLn(':');
  1095. end;
  1096. end;
  1097. ait_symbol :
  1098. begin
  1099. if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
  1100. begin
  1101. AsmWrite(#9'.private_extern ');
  1102. if replaceforbidden then
  1103. AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1104. else
  1105. AsmWriteln(tai_symbol(hp).sym.name);
  1106. end;
  1107. if (target_info.system = system_powerpc64_linux) and
  1108. (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
  1109. AsmWriteLn('.globl _mcount');
  1110. if tai_symbol(hp).is_global then
  1111. begin
  1112. AsmWrite('.globl'#9);
  1113. if replaceforbidden then
  1114. AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1115. else
  1116. AsmWriteln(tai_symbol(hp).sym.name);
  1117. end;
  1118. if (target_info.system = system_powerpc64_linux) and
  1119. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  1120. begin
  1121. AsmWriteLn('.section ".opd", "aw"');
  1122. AsmWriteLn('.align 3');
  1123. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  1124. AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  1125. AsmWriteLn('.previous');
  1126. AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  1127. if (tai_symbol(hp).is_global) then
  1128. AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  1129. AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  1130. { the dotted name is the name of the actual function entry }
  1131. AsmWrite('.');
  1132. end
  1133. else if (target_info.system in systems_aix) and
  1134. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  1135. begin
  1136. if target_info.system=system_powerpc_aix then
  1137. begin
  1138. s:=#9'.long .';
  1139. ch:='2';
  1140. end
  1141. else
  1142. begin
  1143. s:=#9'.llong .';
  1144. ch:='3';
  1145. end;
  1146. AsmWriteLn(#9'.csect '+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+'[DS],'+ch);
  1147. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+':');
  1148. AsmWriteln(s+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+', TOC[tc0], 0');
  1149. AsmWriteln(#9'.csect .text[PR]');
  1150. if (tai_symbol(hp).is_global) then
  1151. AsmWriteLn('.globl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1152. else
  1153. AsmWriteLn('.lglobl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name));
  1154. { the dotted name is the name of the actual function entry }
  1155. AsmWrite('.');
  1156. end
  1157. else
  1158. begin
  1159. if (target_info.system <> system_arm_linux) then
  1160. sepChar := '@'
  1161. else
  1162. sepChar := '#';
  1163. if (tf_needs_symbol_type in target_info.flags) then
  1164. begin
  1165. AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  1166. if (needsObject(tai_symbol(hp))) then
  1167. AsmWriteLn(',' + sepChar + 'object')
  1168. else
  1169. AsmWriteLn(',' + sepChar + 'function');
  1170. end;
  1171. end;
  1172. if replaceforbidden then
  1173. if not(tai_symbol(hp).has_value) then
  1174. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + ':'))
  1175. else
  1176. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value)))
  1177. else if not(tai_symbol(hp).has_value) then
  1178. AsmWriteLn(tai_symbol(hp).sym.name + ':')
  1179. else
  1180. AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
  1181. end;
  1182. {$ifdef arm}
  1183. ait_thumb_func:
  1184. begin
  1185. AsmWriteLn(#9'.thumb_func');
  1186. end;
  1187. ait_thumb_set:
  1188. begin
  1189. AsmWriteLn(#9'.thumb_set '+tai_thumb_set(hp).sym^+', '+tai_thumb_set(hp).value^);
  1190. end;
  1191. {$endif arm}
  1192. ait_set:
  1193. begin
  1194. AsmWriteLn(#9'.set '+tai_set(hp).sym^+', '+tai_set(hp).value^);
  1195. end;
  1196. ait_weak:
  1197. begin
  1198. AsmWriteLn(#9'.weak '+tai_weak(hp).sym^);
  1199. end;
  1200. ait_ent:
  1201. begin
  1202. AsmWrite(#9'.ent'#9);
  1203. if replaceforbidden then
  1204. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_ent(hp).Name))
  1205. else
  1206. AsmWriteLn(tai_ent(hp).Name);
  1207. end;
  1208. ait_ent_end:
  1209. begin
  1210. AsmWrite(#9'.end'#9);
  1211. if replaceforbidden then
  1212. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_ent_end(hp).Name))
  1213. else
  1214. AsmWriteLn(tai_ent_end(hp).Name);
  1215. end;
  1216. ait_symbol_end :
  1217. begin
  1218. if tf_needs_symbol_size in target_info.flags then
  1219. begin
  1220. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  1221. inc(symendcount);
  1222. AsmWriteLn(s+':');
  1223. AsmWrite(#9'.size'#9);
  1224. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1225. AsmWrite('.');
  1226. if replaceforbidden then
  1227. AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1228. else
  1229. AsmWrite(tai_symbol_end(hp).sym.name);
  1230. AsmWrite(', '+s+' - ');
  1231. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1232. AsmWrite('.');
  1233. if replaceforbidden then
  1234. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1235. else
  1236. AsmWriteLn(tai_symbol_end(hp).sym.name);
  1237. end;
  1238. end;
  1239. ait_instruction :
  1240. begin
  1241. WriteInstruction(hp);
  1242. end;
  1243. ait_stab :
  1244. begin
  1245. if assigned(tai_stab(hp).str) then
  1246. begin
  1247. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  1248. AsmWritePChar(tai_stab(hp).str);
  1249. AsmLn;
  1250. end;
  1251. end;
  1252. ait_force_line,
  1253. ait_function_name :
  1254. ;
  1255. ait_cutobject :
  1256. begin
  1257. if SmartAsm then
  1258. begin
  1259. { only reset buffer if nothing has changed }
  1260. if AsmSize=AsmStartSize then
  1261. AsmClear
  1262. else
  1263. begin
  1264. AsmClose;
  1265. DoAssemble;
  1266. AsmCreate(tai_cutobject(hp).place);
  1267. end;
  1268. { avoid empty files }
  1269. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1270. begin
  1271. if tai(hp.next).typ=ait_section then
  1272. LastSecType:=tai_section(hp.next).sectype;
  1273. hp:=tai(hp.next);
  1274. end;
  1275. if LastSecType<>sec_none then
  1276. WriteSection(LastSecType,'',secorder_default,last_align);
  1277. AsmStartSize:=AsmSize;
  1278. end;
  1279. end;
  1280. ait_marker :
  1281. if tai_marker(hp).kind=mark_NoLineInfoStart then
  1282. inc(InlineLevel)
  1283. else if tai_marker(hp).kind=mark_NoLineInfoEnd then
  1284. dec(InlineLevel);
  1285. ait_directive :
  1286. begin
  1287. WriteDirectiveName(tai_directive(hp).directive);
  1288. if tai_directive(hp).name <>'' then
  1289. AsmWrite(tai_directive(hp).name);
  1290. AsmLn;
  1291. end;
  1292. ait_seh_directive :
  1293. begin
  1294. {$ifdef TEST_WIN64_SEH}
  1295. AsmWrite(sehdirectivestr[tai_seh_directive(hp).kind]);
  1296. case tai_seh_directive(hp).datatype of
  1297. sd_none:;
  1298. sd_string:
  1299. begin
  1300. AsmWrite(' '+tai_seh_directive(hp).data.name^);
  1301. if (tai_seh_directive(hp).data.flags and 1)<>0 then
  1302. AsmWrite(',@except');
  1303. if (tai_seh_directive(hp).data.flags and 2)<>0 then
  1304. AsmWrite(',@unwind');
  1305. end;
  1306. sd_reg:
  1307. AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg));
  1308. sd_offset:
  1309. AsmWrite(' '+tostr(tai_seh_directive(hp).data.offset));
  1310. sd_regoffset:
  1311. AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg)+', '+
  1312. tostr(tai_seh_directive(hp).data.offset));
  1313. end;
  1314. AsmLn;
  1315. {$endif TEST_WIN64_SEH}
  1316. end;
  1317. ait_varloc:
  1318. begin
  1319. if tai_varloc(hp).newlocationhi<>NR_NO then
  1320. AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1321. std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
  1322. else
  1323. AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1324. std_regname(tai_varloc(hp).newlocation)));
  1325. AsmLn;
  1326. end;
  1327. else
  1328. internalerror(2006012201);
  1329. end;
  1330. hp:=tai(hp.next);
  1331. end;
  1332. end;
  1333. procedure TGNUAssembler.WriteExtraHeader;
  1334. begin
  1335. end;
  1336. procedure TGNUAssembler.WriteExtraFooter;
  1337. begin
  1338. end;
  1339. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1340. begin
  1341. InstrWriter.WriteInstruction(hp);
  1342. end;
  1343. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1344. begin
  1345. AsmWriteLn(#9'.weak '+s.name);
  1346. end;
  1347. procedure TGNUAssembler.WriteAixStringConst(hp: tai_string);
  1348. type
  1349. tterminationkind = (term_none,term_string,term_nostring);
  1350. var
  1351. i: longint;
  1352. pos: longint;
  1353. s: string;
  1354. ch: char;
  1355. instring: boolean;
  1356. procedure newstatement(terminationkind: tterminationkind);
  1357. begin
  1358. case terminationkind of
  1359. term_none: ;
  1360. term_string:
  1361. AsmWriteLn('"');
  1362. term_nostring:
  1363. AsmLn;
  1364. end;
  1365. AsmWrite(#9'.byte'#9);
  1366. pos:=20;
  1367. instring:=false;
  1368. end;
  1369. begin
  1370. pos:=0;
  1371. for i:=1 to hp.len do
  1372. begin
  1373. if pos=0 then
  1374. newstatement(term_none);
  1375. ch:=hp.str[i-1];
  1376. case ch of
  1377. #0..#31,
  1378. #127..#255 :
  1379. begin
  1380. if instring then
  1381. newstatement(term_string);
  1382. if pos=20 then
  1383. s:=tostr(ord(ch))
  1384. else
  1385. s:=', '+tostr(ord(ch))
  1386. end;
  1387. '"' :
  1388. if instring then
  1389. s:='""'
  1390. else
  1391. begin
  1392. if pos<>20 then
  1393. newstatement(term_nostring);
  1394. s:='"""';
  1395. instring:=true;
  1396. end;
  1397. else
  1398. if not instring then
  1399. begin
  1400. if (pos<>20) then
  1401. newstatement(term_nostring);
  1402. s:='"'+ch;
  1403. instring:=true;
  1404. end
  1405. else
  1406. s:=ch;
  1407. end;
  1408. AsmWrite(s);
  1409. inc(pos,length(s));
  1410. if (pos>line_length) or (i=tai_string(hp).len) then
  1411. begin
  1412. if instring then
  1413. AsmWriteLn('"')
  1414. else
  1415. AsmLn;
  1416. pos:=0;
  1417. end;
  1418. end;
  1419. end;
  1420. procedure TGNUAssembler.WriteAixIntConst(hp: tai_const);
  1421. var
  1422. pos, size: longint;
  1423. begin
  1424. { only big endian AIX supported for now }
  1425. if target_info.endian<>endian_big then
  1426. internalerror(2012010401);
  1427. { limitation: can only write 4 bytes at a time }
  1428. pos:=0;
  1429. size:=tai_const(hp).size;
  1430. while pos<(size-4) do
  1431. begin
  1432. AsmWrite(#9'.vbyte'#9'4, ');
  1433. AsmWriteln(tostr(longint(tai_const(hp).value shr ((size-pos-4)*8))));
  1434. inc(pos,4);
  1435. end;
  1436. AsmWrite(#9'.vbyte'#9);
  1437. AsmWrite(tostr(size-pos));
  1438. AsmWrite(', ');
  1439. case size-pos of
  1440. 1: AsmWrite(tostr(byte(tai_const(hp).value)));
  1441. 2: AsmWrite(tostr(word(tai_const(hp).value)));
  1442. 4: AsmWrite(tostr(longint(tai_const(hp).value)));
  1443. else
  1444. internalerror(2012010402);
  1445. end;
  1446. end;
  1447. procedure TGNUAssembler.WriteUnalignedIntConst(hp: tai_const);
  1448. var
  1449. pos, size: longint;
  1450. begin
  1451. size:=tai_const(hp).size;
  1452. AsmWrite(#9'.byte'#9);
  1453. if target_info.endian=endian_big then
  1454. begin
  1455. pos:=size-1;
  1456. while pos>=0 do
  1457. begin
  1458. AsmWrite(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1459. dec(pos);
  1460. if pos>=0 then
  1461. AsmWrite(', ')
  1462. else
  1463. AsmLn;
  1464. end;
  1465. end
  1466. else
  1467. begin
  1468. pos:=0;
  1469. while pos<size do
  1470. begin
  1471. AsmWriteln(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1472. inc(pos);
  1473. if pos<=size then
  1474. AsmWrite(', ')
  1475. else
  1476. AsmLn;
  1477. end;
  1478. end;
  1479. AsmLn;
  1480. end;
  1481. procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
  1482. begin
  1483. AsmWrite('.'+directivestr[dir]+' ');
  1484. end;
  1485. procedure TGNUAssembler.WriteAsmList;
  1486. var
  1487. n : string;
  1488. hal : tasmlisttype;
  1489. i: longint;
  1490. begin
  1491. {$ifdef EXTDEBUG}
  1492. if current_module.mainsource<>'' then
  1493. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource);
  1494. {$endif}
  1495. if current_module.mainsource<>'' then
  1496. n:=ExtractFileName(current_module.mainsource)
  1497. else
  1498. n:=InputFileName;
  1499. { gcc does not add it either for Darwin. Grep for
  1500. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1501. }
  1502. if not(target_info.system in systems_darwin) then
  1503. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1504. WriteExtraHeader;
  1505. AsmStartSize:=AsmSize;
  1506. symendcount:=0;
  1507. for hal:=low(TasmlistType) to high(TasmlistType) do
  1508. begin
  1509. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1510. writetree(current_asmdata.asmlists[hal]);
  1511. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1512. end;
  1513. { add weak symbol markers }
  1514. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1515. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1516. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1517. if create_smartlink_sections and
  1518. (target_info.system in systems_darwin) then
  1519. AsmWriteLn(#9'.subsections_via_symbols');
  1520. { "no executable stack" marker for Linux }
  1521. if (target_info.system in systems_linux) and
  1522. not(cs_executable_stack in current_settings.moduleswitches) then
  1523. begin
  1524. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1525. end;
  1526. AsmLn;
  1527. {$ifdef EXTDEBUG}
  1528. if current_module.mainsource<>'' then
  1529. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
  1530. {$endif EXTDEBUG}
  1531. end;
  1532. {****************************************************************************}
  1533. { Apple/GNU Assembler writer }
  1534. {****************************************************************************}
  1535. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1536. begin
  1537. if (target_info.system in systems_darwin) then
  1538. case atype of
  1539. sec_bss:
  1540. { all bss (lcomm) symbols are automatically put in the right }
  1541. { place by using the lcomm assembler directive }
  1542. atype := sec_none;
  1543. sec_debug_frame,
  1544. sec_eh_frame:
  1545. begin
  1546. result := '.section __DWARF,__debug_info,regular,debug';
  1547. exit;
  1548. end;
  1549. sec_debug_line:
  1550. begin
  1551. result := '.section __DWARF,__debug_line,regular,debug';
  1552. exit;
  1553. end;
  1554. sec_debug_info:
  1555. begin
  1556. result := '.section __DWARF,__debug_info,regular,debug';
  1557. exit;
  1558. end;
  1559. sec_debug_abbrev:
  1560. begin
  1561. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1562. exit;
  1563. end;
  1564. sec_rodata:
  1565. begin
  1566. result := '.const_data';
  1567. exit;
  1568. end;
  1569. sec_rodata_norel:
  1570. begin
  1571. result := '.const';
  1572. exit;
  1573. end;
  1574. sec_fpc:
  1575. begin
  1576. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1577. exit;
  1578. end;
  1579. sec_code:
  1580. begin
  1581. if (aname='fpc_geteipasebx') or
  1582. (aname='fpc_geteipasecx') then
  1583. begin
  1584. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1585. #10'.private_extern '+aname;
  1586. exit;
  1587. end;
  1588. end;
  1589. sec_data_nonlazy:
  1590. begin
  1591. result:='.section __DATA, __nl_symbol_ptr,non_lazy_symbol_pointers';
  1592. exit;
  1593. end;
  1594. sec_data_lazy:
  1595. begin
  1596. result:='.section __DATA, __la_symbol_ptr,lazy_symbol_pointers';
  1597. exit;
  1598. end;
  1599. sec_init_func:
  1600. begin
  1601. result:='.section __DATA, __mod_init_func, mod_init_funcs';
  1602. exit;
  1603. end;
  1604. sec_term_func:
  1605. begin
  1606. result:='.section __DATA, __mod_term_func, mod_term_funcs';
  1607. exit;
  1608. end;
  1609. sec_objc_protocol_ext:
  1610. begin
  1611. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1612. exit;
  1613. end;
  1614. sec_objc_class_ext:
  1615. begin
  1616. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1617. exit;
  1618. end;
  1619. sec_objc_property:
  1620. begin
  1621. result:='.section __OBJC, __property, regular, no_dead_strip';
  1622. exit;
  1623. end;
  1624. sec_objc_image_info:
  1625. begin
  1626. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1627. exit;
  1628. end;
  1629. sec_objc_cstring_object:
  1630. begin
  1631. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1632. exit;
  1633. end;
  1634. sec_objc_sel_fixup:
  1635. begin
  1636. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1637. exit;
  1638. end;
  1639. sec_objc_message_refs:
  1640. begin
  1641. if (target_info.system in systems_objc_nfabi) then
  1642. begin
  1643. result:='.section __DATA, __objc_selrefs, literal_pointers, no_dead_strip';
  1644. exit;
  1645. end;
  1646. end;
  1647. sec_objc_cls_refs:
  1648. begin
  1649. if (target_info.system in systems_objc_nfabi) then
  1650. begin
  1651. result:='.section __DATA, __objc_clsrefs, regular, no_dead_strip';
  1652. exit;
  1653. end;
  1654. end;
  1655. sec_objc_meth_var_names,
  1656. sec_objc_class_names:
  1657. begin
  1658. if (target_info.system in systems_objc_nfabi) then
  1659. begin
  1660. result:='.cstring';
  1661. exit
  1662. end;
  1663. end;
  1664. sec_objc_inst_meth,
  1665. sec_objc_cls_meth,
  1666. sec_objc_cat_inst_meth,
  1667. sec_objc_cat_cls_meth:
  1668. begin
  1669. if (target_info.system in systems_objc_nfabi) then
  1670. begin
  1671. result:='.section __DATA, __objc_const';
  1672. exit;
  1673. end;
  1674. end;
  1675. sec_objc_meta_class,
  1676. sec_objc_class:
  1677. begin
  1678. if (target_info.system in systems_objc_nfabi) then
  1679. begin
  1680. result:='.section __DATA, __objc_data';
  1681. exit;
  1682. end;
  1683. end;
  1684. sec_objc_sup_refs:
  1685. begin
  1686. result:='.section __DATA, __objc_superrefs, regular, no_dead_strip';
  1687. exit
  1688. end;
  1689. sec_objc_classlist:
  1690. begin
  1691. result:='.section __DATA, __objc_classlist, regular, no_dead_strip';
  1692. exit
  1693. end;
  1694. sec_objc_nlclasslist:
  1695. begin
  1696. result:='.section __DATA, __objc_nlclasslist, regular, no_dead_strip';
  1697. exit
  1698. end;
  1699. sec_objc_catlist:
  1700. begin
  1701. result:='.section __DATA, __objc_catlist, regular, no_dead_strip';
  1702. exit
  1703. end;
  1704. sec_objc_nlcatlist:
  1705. begin
  1706. result:='.section __DATA, __objc_nlcatlist, regular, no_dead_strip';
  1707. exit
  1708. end;
  1709. sec_objc_protolist:
  1710. begin
  1711. result:='.section __DATA, __objc_protolist, coalesced, no_dead_strip';
  1712. exit;
  1713. end;
  1714. end;
  1715. result := inherited sectionname(atype,aname,aorder);
  1716. end;
  1717. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1718. begin
  1719. AsmWriteLn(#9'.weak_reference '+s.name);
  1720. end;
  1721. {****************************************************************************}
  1722. { a.out/GNU Assembler writer }
  1723. {****************************************************************************}
  1724. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1725. const
  1726. (* Translation table - replace unsupported section types with basic ones. *)
  1727. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1728. sec_none,
  1729. sec_none,
  1730. sec_code,
  1731. sec_data,
  1732. sec_data (* sec_rodata *),
  1733. sec_data (* sec_rodata_norel *),
  1734. sec_bss,
  1735. sec_data (* sec_threadvar *),
  1736. { used for wince exception handling }
  1737. sec_code (* sec_pdata *),
  1738. { used for darwin import stubs }
  1739. sec_code (* sec_stub *),
  1740. sec_data,(* sec_data_nonlazy *)
  1741. sec_data,(* sec_data_lazy *)
  1742. sec_data,(* sec_init_func *)
  1743. sec_data,(* sec_term_func *)
  1744. { stabs }
  1745. sec_stab,sec_stabstr,
  1746. { win32 }
  1747. sec_data (* sec_idata2 *),
  1748. sec_data (* sec_idata4 *),
  1749. sec_data (* sec_idata5 *),
  1750. sec_data (* sec_idata6 *),
  1751. sec_data (* sec_idata7 *),
  1752. sec_data (* sec_edata *),
  1753. { C++ exception handling unwinding (uses dwarf) }
  1754. sec_eh_frame,
  1755. { dwarf }
  1756. sec_debug_frame,
  1757. sec_debug_info,
  1758. sec_debug_line,
  1759. sec_debug_abbrev,
  1760. { ELF resources (+ references to stabs debug information sections) }
  1761. sec_code (* sec_fpc *),
  1762. { Table of contents section }
  1763. sec_code (* sec_toc *),
  1764. sec_code (* sec_init *),
  1765. sec_code (* sec_fini *),
  1766. sec_none (* sec_objc_class *),
  1767. sec_none (* sec_objc_meta_class *),
  1768. sec_none (* sec_objc_cat_cls_meth *),
  1769. sec_none (* sec_objc_cat_inst_meth *),
  1770. sec_none (* sec_objc_protocol *),
  1771. sec_none (* sec_objc_string_object *),
  1772. sec_none (* sec_objc_cls_meth *),
  1773. sec_none (* sec_objc_inst_meth *),
  1774. sec_none (* sec_objc_cls_refs *),
  1775. sec_none (* sec_objc_message_refs *),
  1776. sec_none (* sec_objc_symbols *),
  1777. sec_none (* sec_objc_category *),
  1778. sec_none (* sec_objc_class_vars *),
  1779. sec_none (* sec_objc_instance_vars *),
  1780. sec_none (* sec_objc_module_info *),
  1781. sec_none (* sec_objc_class_names *),
  1782. sec_none (* sec_objc_meth_var_types *),
  1783. sec_none (* sec_objc_meth_var_names *),
  1784. sec_none (* sec_objc_selector_strs *),
  1785. sec_none (* sec_objc_protocol_ext *),
  1786. sec_none (* sec_objc_class_ext *),
  1787. sec_none (* sec_objc_property *),
  1788. sec_none (* sec_objc_image_info *),
  1789. sec_none (* sec_objc_cstring_object *),
  1790. sec_none (* sec_objc_sel_fixup *),
  1791. sec_none (* sec_objc_data *),
  1792. sec_none (* sec_objc_const *),
  1793. sec_none (* sec_objc_sup_refs *),
  1794. sec_none (* sec_data_coalesced *),
  1795. sec_none (* sec_objc_classlist *),
  1796. sec_none (* sec_objc_nlclasslist *),
  1797. sec_none (* sec_objc_catlist *),
  1798. sec_none (* sec_objc_nlcatlist *),
  1799. sec_none (* sec_objc_protlist *)
  1800. );
  1801. begin
  1802. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1803. end;
  1804. {****************************************************************************}
  1805. { Abstract Instruction Writer }
  1806. {****************************************************************************}
  1807. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1808. begin
  1809. inherited create;
  1810. owner := _owner;
  1811. end;
  1812. end.