aggas.pas 68 KB

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