aggas.pas 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950
  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. {$endif arm}
  1188. ait_ent:
  1189. begin
  1190. AsmWrite(#9'.ent'#9);
  1191. if replaceforbidden then
  1192. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_ent(hp).Name))
  1193. else
  1194. AsmWriteLn(tai_ent(hp).Name);
  1195. end;
  1196. ait_ent_end:
  1197. begin
  1198. AsmWrite(#9'.end'#9);
  1199. if replaceforbidden then
  1200. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_ent_end(hp).Name))
  1201. else
  1202. AsmWriteLn(tai_ent_end(hp).Name);
  1203. end;
  1204. ait_symbol_end :
  1205. begin
  1206. if tf_needs_symbol_size in target_info.flags then
  1207. begin
  1208. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  1209. inc(symendcount);
  1210. AsmWriteLn(s+':');
  1211. AsmWrite(#9'.size'#9);
  1212. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1213. AsmWrite('.');
  1214. if replaceforbidden then
  1215. AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1216. else
  1217. AsmWrite(tai_symbol_end(hp).sym.name);
  1218. AsmWrite(', '+s+' - ');
  1219. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1220. AsmWrite('.');
  1221. if replaceforbidden then
  1222. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1223. else
  1224. AsmWriteLn(tai_symbol_end(hp).sym.name);
  1225. end;
  1226. end;
  1227. ait_instruction :
  1228. begin
  1229. WriteInstruction(hp);
  1230. end;
  1231. ait_stab :
  1232. begin
  1233. if assigned(tai_stab(hp).str) then
  1234. begin
  1235. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  1236. AsmWritePChar(tai_stab(hp).str);
  1237. AsmLn;
  1238. end;
  1239. end;
  1240. ait_force_line,
  1241. ait_function_name :
  1242. ;
  1243. ait_cutobject :
  1244. begin
  1245. if SmartAsm then
  1246. begin
  1247. { only reset buffer if nothing has changed }
  1248. if AsmSize=AsmStartSize then
  1249. AsmClear
  1250. else
  1251. begin
  1252. AsmClose;
  1253. DoAssemble;
  1254. AsmCreate(tai_cutobject(hp).place);
  1255. end;
  1256. { avoid empty files }
  1257. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1258. begin
  1259. if tai(hp.next).typ=ait_section then
  1260. LastSecType:=tai_section(hp.next).sectype;
  1261. hp:=tai(hp.next);
  1262. end;
  1263. if LastSecType<>sec_none then
  1264. WriteSection(LastSecType,'',secorder_default,last_align);
  1265. AsmStartSize:=AsmSize;
  1266. end;
  1267. end;
  1268. ait_marker :
  1269. if tai_marker(hp).kind=mark_NoLineInfoStart then
  1270. inc(InlineLevel)
  1271. else if tai_marker(hp).kind=mark_NoLineInfoEnd then
  1272. dec(InlineLevel);
  1273. ait_directive :
  1274. begin
  1275. WriteDirectiveName(tai_directive(hp).directive);
  1276. if tai_directive(hp).name <>'' then
  1277. AsmWrite(tai_directive(hp).name);
  1278. AsmLn;
  1279. end;
  1280. ait_seh_directive :
  1281. begin
  1282. {$ifdef TEST_WIN64_SEH}
  1283. AsmWrite(sehdirectivestr[tai_seh_directive(hp).kind]);
  1284. case tai_seh_directive(hp).datatype of
  1285. sd_none:;
  1286. sd_string:
  1287. begin
  1288. AsmWrite(' '+tai_seh_directive(hp).data.name^);
  1289. if (tai_seh_directive(hp).data.flags and 1)<>0 then
  1290. AsmWrite(',@except');
  1291. if (tai_seh_directive(hp).data.flags and 2)<>0 then
  1292. AsmWrite(',@unwind');
  1293. end;
  1294. sd_reg:
  1295. AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg));
  1296. sd_offset:
  1297. AsmWrite(' '+tostr(tai_seh_directive(hp).data.offset));
  1298. sd_regoffset:
  1299. AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg)+', '+
  1300. tostr(tai_seh_directive(hp).data.offset));
  1301. end;
  1302. AsmLn;
  1303. {$endif TEST_WIN64_SEH}
  1304. end;
  1305. ait_varloc:
  1306. begin
  1307. if tai_varloc(hp).newlocationhi<>NR_NO then
  1308. AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1309. std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
  1310. else
  1311. AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1312. std_regname(tai_varloc(hp).newlocation)));
  1313. AsmLn;
  1314. end;
  1315. else
  1316. internalerror(2006012201);
  1317. end;
  1318. hp:=tai(hp.next);
  1319. end;
  1320. end;
  1321. procedure TGNUAssembler.WriteExtraHeader;
  1322. begin
  1323. end;
  1324. procedure TGNUAssembler.WriteExtraFooter;
  1325. begin
  1326. end;
  1327. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1328. begin
  1329. InstrWriter.WriteInstruction(hp);
  1330. end;
  1331. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1332. begin
  1333. AsmWriteLn(#9'.weak '+s.name);
  1334. end;
  1335. procedure TGNUAssembler.WriteAixStringConst(hp: tai_string);
  1336. type
  1337. tterminationkind = (term_none,term_string,term_nostring);
  1338. var
  1339. i: longint;
  1340. pos: longint;
  1341. s: string;
  1342. ch: char;
  1343. instring: boolean;
  1344. procedure newstatement(terminationkind: tterminationkind);
  1345. begin
  1346. case terminationkind of
  1347. term_none: ;
  1348. term_string:
  1349. AsmWriteLn('"');
  1350. term_nostring:
  1351. AsmLn;
  1352. end;
  1353. AsmWrite(#9'.byte'#9);
  1354. pos:=20;
  1355. instring:=false;
  1356. end;
  1357. begin
  1358. pos:=0;
  1359. for i:=1 to hp.len do
  1360. begin
  1361. if pos=0 then
  1362. newstatement(term_none);
  1363. ch:=hp.str[i-1];
  1364. case ch of
  1365. #0..#31,
  1366. #127..#255 :
  1367. begin
  1368. if instring then
  1369. newstatement(term_string);
  1370. if pos=20 then
  1371. s:=tostr(ord(ch))
  1372. else
  1373. s:=', '+tostr(ord(ch))
  1374. end;
  1375. '"' :
  1376. if instring then
  1377. s:='""'
  1378. else
  1379. begin
  1380. if pos<>20 then
  1381. newstatement(term_nostring);
  1382. s:='"""';
  1383. instring:=true;
  1384. end;
  1385. else
  1386. if not instring then
  1387. begin
  1388. if (pos<>20) then
  1389. newstatement(term_nostring);
  1390. s:='"'+ch;
  1391. instring:=true;
  1392. end
  1393. else
  1394. s:=ch;
  1395. end;
  1396. AsmWrite(s);
  1397. inc(pos,length(s));
  1398. if (pos>line_length) or (i=tai_string(hp).len) then
  1399. begin
  1400. if instring then
  1401. AsmWriteLn('"')
  1402. else
  1403. AsmLn;
  1404. pos:=0;
  1405. end;
  1406. end;
  1407. end;
  1408. procedure TGNUAssembler.WriteAixIntConst(hp: tai_const);
  1409. var
  1410. pos, size: longint;
  1411. begin
  1412. { only big endian AIX supported for now }
  1413. if target_info.endian<>endian_big then
  1414. internalerror(2012010401);
  1415. { limitation: can only write 4 bytes at a time }
  1416. pos:=0;
  1417. size:=tai_const(hp).size;
  1418. while pos<(size-4) do
  1419. begin
  1420. AsmWrite(#9'.vbyte'#9'4, ');
  1421. AsmWriteln(tostr(longint(tai_const(hp).value shr ((size-pos-4)*8))));
  1422. inc(pos,4);
  1423. end;
  1424. AsmWrite(#9'.vbyte'#9);
  1425. AsmWrite(tostr(size-pos));
  1426. AsmWrite(', ');
  1427. case size-pos of
  1428. 1: AsmWrite(tostr(byte(tai_const(hp).value)));
  1429. 2: AsmWrite(tostr(word(tai_const(hp).value)));
  1430. 4: AsmWrite(tostr(longint(tai_const(hp).value)));
  1431. else
  1432. internalerror(2012010402);
  1433. end;
  1434. end;
  1435. procedure TGNUAssembler.WriteUnalignedIntConst(hp: tai_const);
  1436. var
  1437. pos, size: longint;
  1438. begin
  1439. size:=tai_const(hp).size;
  1440. AsmWrite(#9'.byte'#9);
  1441. if target_info.endian=endian_big then
  1442. begin
  1443. pos:=size-1;
  1444. while pos>=0 do
  1445. begin
  1446. AsmWrite(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1447. dec(pos);
  1448. if pos>=0 then
  1449. AsmWrite(', ')
  1450. else
  1451. AsmLn;
  1452. end;
  1453. end
  1454. else
  1455. begin
  1456. pos:=0;
  1457. while pos<size do
  1458. begin
  1459. AsmWriteln(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1460. inc(pos);
  1461. if pos<=size then
  1462. AsmWrite(', ')
  1463. else
  1464. AsmLn;
  1465. end;
  1466. end;
  1467. AsmLn;
  1468. end;
  1469. procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
  1470. begin
  1471. AsmWrite('.'+directivestr[dir]+' ');
  1472. end;
  1473. procedure TGNUAssembler.WriteAsmList;
  1474. var
  1475. n : string;
  1476. hal : tasmlisttype;
  1477. i: longint;
  1478. begin
  1479. {$ifdef EXTDEBUG}
  1480. if current_module.mainsource<>'' then
  1481. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource);
  1482. {$endif}
  1483. if current_module.mainsource<>'' then
  1484. n:=ExtractFileName(current_module.mainsource)
  1485. else
  1486. n:=InputFileName;
  1487. { gcc does not add it either for Darwin. Grep for
  1488. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1489. }
  1490. if not(target_info.system in systems_darwin) then
  1491. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1492. WriteExtraHeader;
  1493. AsmStartSize:=AsmSize;
  1494. symendcount:=0;
  1495. for hal:=low(TasmlistType) to high(TasmlistType) do
  1496. begin
  1497. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1498. writetree(current_asmdata.asmlists[hal]);
  1499. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1500. end;
  1501. { add weak symbol markers }
  1502. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1503. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1504. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1505. if create_smartlink_sections and
  1506. (target_info.system in systems_darwin) then
  1507. AsmWriteLn(#9'.subsections_via_symbols');
  1508. { "no executable stack" marker for Linux }
  1509. if (target_info.system in systems_linux) and
  1510. not(cs_executable_stack in current_settings.moduleswitches) then
  1511. begin
  1512. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1513. end;
  1514. AsmLn;
  1515. {$ifdef EXTDEBUG}
  1516. if current_module.mainsource<>'' then
  1517. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
  1518. {$endif EXTDEBUG}
  1519. end;
  1520. {****************************************************************************}
  1521. { Apple/GNU Assembler writer }
  1522. {****************************************************************************}
  1523. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1524. begin
  1525. if (target_info.system in systems_darwin) then
  1526. case atype of
  1527. sec_bss:
  1528. { all bss (lcomm) symbols are automatically put in the right }
  1529. { place by using the lcomm assembler directive }
  1530. atype := sec_none;
  1531. sec_debug_frame,
  1532. sec_eh_frame:
  1533. begin
  1534. result := '.section __DWARF,__debug_info,regular,debug';
  1535. exit;
  1536. end;
  1537. sec_debug_line:
  1538. begin
  1539. result := '.section __DWARF,__debug_line,regular,debug';
  1540. exit;
  1541. end;
  1542. sec_debug_info:
  1543. begin
  1544. result := '.section __DWARF,__debug_info,regular,debug';
  1545. exit;
  1546. end;
  1547. sec_debug_abbrev:
  1548. begin
  1549. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1550. exit;
  1551. end;
  1552. sec_rodata:
  1553. begin
  1554. result := '.const_data';
  1555. exit;
  1556. end;
  1557. sec_rodata_norel:
  1558. begin
  1559. result := '.const';
  1560. exit;
  1561. end;
  1562. sec_fpc:
  1563. begin
  1564. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1565. exit;
  1566. end;
  1567. sec_code:
  1568. begin
  1569. if (aname='fpc_geteipasebx') or
  1570. (aname='fpc_geteipasecx') then
  1571. begin
  1572. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1573. #10'.private_extern '+aname;
  1574. exit;
  1575. end;
  1576. end;
  1577. sec_data_nonlazy:
  1578. begin
  1579. result:='.section __DATA, __nl_symbol_ptr,non_lazy_symbol_pointers';
  1580. exit;
  1581. end;
  1582. sec_data_lazy:
  1583. begin
  1584. result:='.section __DATA, __la_symbol_ptr,lazy_symbol_pointers';
  1585. exit;
  1586. end;
  1587. sec_init_func:
  1588. begin
  1589. result:='.section __DATA, __mod_init_func, mod_init_funcs';
  1590. exit;
  1591. end;
  1592. sec_term_func:
  1593. begin
  1594. result:='.section __DATA, __mod_term_func, mod_term_funcs';
  1595. exit;
  1596. end;
  1597. sec_objc_protocol_ext:
  1598. begin
  1599. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1600. exit;
  1601. end;
  1602. sec_objc_class_ext:
  1603. begin
  1604. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1605. exit;
  1606. end;
  1607. sec_objc_property:
  1608. begin
  1609. result:='.section __OBJC, __property, regular, no_dead_strip';
  1610. exit;
  1611. end;
  1612. sec_objc_image_info:
  1613. begin
  1614. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1615. exit;
  1616. end;
  1617. sec_objc_cstring_object:
  1618. begin
  1619. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1620. exit;
  1621. end;
  1622. sec_objc_sel_fixup:
  1623. begin
  1624. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1625. exit;
  1626. end;
  1627. sec_objc_message_refs:
  1628. begin
  1629. if (target_info.system in systems_objc_nfabi) then
  1630. begin
  1631. result:='.section __DATA, __objc_selrefs, literal_pointers, no_dead_strip';
  1632. exit;
  1633. end;
  1634. end;
  1635. sec_objc_cls_refs:
  1636. begin
  1637. if (target_info.system in systems_objc_nfabi) then
  1638. begin
  1639. result:='.section __DATA, __objc_clsrefs, regular, no_dead_strip';
  1640. exit;
  1641. end;
  1642. end;
  1643. sec_objc_meth_var_names,
  1644. sec_objc_class_names:
  1645. begin
  1646. if (target_info.system in systems_objc_nfabi) then
  1647. begin
  1648. result:='.cstring';
  1649. exit
  1650. end;
  1651. end;
  1652. sec_objc_inst_meth,
  1653. sec_objc_cls_meth,
  1654. sec_objc_cat_inst_meth,
  1655. sec_objc_cat_cls_meth:
  1656. begin
  1657. if (target_info.system in systems_objc_nfabi) then
  1658. begin
  1659. result:='.section __DATA, __objc_const';
  1660. exit;
  1661. end;
  1662. end;
  1663. sec_objc_meta_class,
  1664. sec_objc_class:
  1665. begin
  1666. if (target_info.system in systems_objc_nfabi) then
  1667. begin
  1668. result:='.section __DATA, __objc_data';
  1669. exit;
  1670. end;
  1671. end;
  1672. sec_objc_sup_refs:
  1673. begin
  1674. result:='.section __DATA, __objc_superrefs, regular, no_dead_strip';
  1675. exit
  1676. end;
  1677. sec_objc_classlist:
  1678. begin
  1679. result:='.section __DATA, __objc_classlist, regular, no_dead_strip';
  1680. exit
  1681. end;
  1682. sec_objc_nlclasslist:
  1683. begin
  1684. result:='.section __DATA, __objc_nlclasslist, regular, no_dead_strip';
  1685. exit
  1686. end;
  1687. sec_objc_catlist:
  1688. begin
  1689. result:='.section __DATA, __objc_catlist, regular, no_dead_strip';
  1690. exit
  1691. end;
  1692. sec_objc_nlcatlist:
  1693. begin
  1694. result:='.section __DATA, __objc_nlcatlist, regular, no_dead_strip';
  1695. exit
  1696. end;
  1697. sec_objc_protolist:
  1698. begin
  1699. result:='.section __DATA, __objc_protolist, coalesced, no_dead_strip';
  1700. exit;
  1701. end;
  1702. end;
  1703. result := inherited sectionname(atype,aname,aorder);
  1704. end;
  1705. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1706. begin
  1707. AsmWriteLn(#9'.weak_reference '+s.name);
  1708. end;
  1709. {****************************************************************************}
  1710. { a.out/GNU Assembler writer }
  1711. {****************************************************************************}
  1712. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1713. const
  1714. (* Translation table - replace unsupported section types with basic ones. *)
  1715. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1716. sec_none,
  1717. sec_none,
  1718. sec_code,
  1719. sec_data,
  1720. sec_data (* sec_rodata *),
  1721. sec_data (* sec_rodata_norel *),
  1722. sec_bss,
  1723. sec_data (* sec_threadvar *),
  1724. { used for wince exception handling }
  1725. sec_code (* sec_pdata *),
  1726. { used for darwin import stubs }
  1727. sec_code (* sec_stub *),
  1728. sec_data,(* sec_data_nonlazy *)
  1729. sec_data,(* sec_data_lazy *)
  1730. sec_data,(* sec_init_func *)
  1731. sec_data,(* sec_term_func *)
  1732. { stabs }
  1733. sec_stab,sec_stabstr,
  1734. { win32 }
  1735. sec_data (* sec_idata2 *),
  1736. sec_data (* sec_idata4 *),
  1737. sec_data (* sec_idata5 *),
  1738. sec_data (* sec_idata6 *),
  1739. sec_data (* sec_idata7 *),
  1740. sec_data (* sec_edata *),
  1741. { C++ exception handling unwinding (uses dwarf) }
  1742. sec_eh_frame,
  1743. { dwarf }
  1744. sec_debug_frame,
  1745. sec_debug_info,
  1746. sec_debug_line,
  1747. sec_debug_abbrev,
  1748. { ELF resources (+ references to stabs debug information sections) }
  1749. sec_code (* sec_fpc *),
  1750. { Table of contents section }
  1751. sec_code (* sec_toc *),
  1752. sec_code (* sec_init *),
  1753. sec_code (* sec_fini *),
  1754. sec_none (* sec_objc_class *),
  1755. sec_none (* sec_objc_meta_class *),
  1756. sec_none (* sec_objc_cat_cls_meth *),
  1757. sec_none (* sec_objc_cat_inst_meth *),
  1758. sec_none (* sec_objc_protocol *),
  1759. sec_none (* sec_objc_string_object *),
  1760. sec_none (* sec_objc_cls_meth *),
  1761. sec_none (* sec_objc_inst_meth *),
  1762. sec_none (* sec_objc_cls_refs *),
  1763. sec_none (* sec_objc_message_refs *),
  1764. sec_none (* sec_objc_symbols *),
  1765. sec_none (* sec_objc_category *),
  1766. sec_none (* sec_objc_class_vars *),
  1767. sec_none (* sec_objc_instance_vars *),
  1768. sec_none (* sec_objc_module_info *),
  1769. sec_none (* sec_objc_class_names *),
  1770. sec_none (* sec_objc_meth_var_types *),
  1771. sec_none (* sec_objc_meth_var_names *),
  1772. sec_none (* sec_objc_selector_strs *),
  1773. sec_none (* sec_objc_protocol_ext *),
  1774. sec_none (* sec_objc_class_ext *),
  1775. sec_none (* sec_objc_property *),
  1776. sec_none (* sec_objc_image_info *),
  1777. sec_none (* sec_objc_cstring_object *),
  1778. sec_none (* sec_objc_sel_fixup *),
  1779. sec_none (* sec_objc_data *),
  1780. sec_none (* sec_objc_const *),
  1781. sec_none (* sec_objc_sup_refs *),
  1782. sec_none (* sec_data_coalesced *),
  1783. sec_none (* sec_objc_classlist *),
  1784. sec_none (* sec_objc_nlclasslist *),
  1785. sec_none (* sec_objc_catlist *),
  1786. sec_none (* sec_objc_nlcatlist *),
  1787. sec_none (* sec_objc_protlist *)
  1788. );
  1789. begin
  1790. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1791. end;
  1792. {****************************************************************************}
  1793. { Abstract Instruction Writer }
  1794. {****************************************************************************}
  1795. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1796. begin
  1797. inherited create;
  1798. owner := _owner;
  1799. end;
  1800. end.