aggas.pas 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800
  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',
  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',
  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. { old Amiga GNU AS doesn't support .section .fpc }
  306. if (atype=sec_fpc) and (target_info.system = system_m68k_amiga) 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:
  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_amiga: ; { amiga has old GNU AS (2.14), which blews up from .section (KB) }
  394. system_powerpc_darwin,
  395. system_i386_darwin,
  396. system_i386_iphonesim,
  397. system_powerpc64_darwin,
  398. system_x86_64_darwin,
  399. system_arm_darwin,
  400. system_aarch64_darwin,
  401. system_x86_64_iphonesim,
  402. system_powerpc_aix,
  403. system_powerpc64_aix:
  404. begin
  405. if (atype in [sec_stub]) then
  406. writer.AsmWrite('.section ');
  407. end
  408. else
  409. writer.AsmWrite('.section ');
  410. end;
  411. s:=sectionname(atype,aname,aorder);
  412. writer.AsmWrite(s);
  413. case atype of
  414. sec_fpc :
  415. if aname = 'resptrs' then
  416. writer.AsmWrite(', "a", @progbits');
  417. sec_stub :
  418. begin
  419. case target_info.system of
  420. { there are processor-independent shortcuts available }
  421. { for this, namely .symbol_stub and .picsymbol_stub, but }
  422. { they don't work and gcc doesn't use them either... }
  423. system_powerpc_darwin,
  424. system_powerpc64_darwin:
  425. if (cs_create_pic in current_settings.moduleswitches) then
  426. writer.AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
  427. else
  428. writer.AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
  429. system_i386_darwin,
  430. system_i386_iphonesim:
  431. writer.AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
  432. system_arm_darwin:
  433. if (cs_create_pic in current_settings.moduleswitches) then
  434. writer.AsmWriteln('__TEXT,__picsymbolstub4,symbol_stubs,none,16')
  435. else
  436. writer.AsmWriteln('__TEXT,__symbol_stub4,symbol_stubs,none,12')
  437. { darwin/(x86-64/AArch64) uses PC-based GOT addressing, no
  438. explicit symbol stubs }
  439. else
  440. internalerror(2006031101);
  441. end;
  442. end;
  443. else
  444. { GNU AS won't recognize '.text.n_something' section name as belonging
  445. to '.text' and assigns default attributes to it, which is not
  446. always correct. We have to fix it.
  447. TODO: This likely applies to all systems which smartlink without
  448. creating libraries }
  449. if (target_info.system in [system_i386_win32,system_x86_64_win64]) and
  450. is_smart_section(atype) and (aname<>'') then
  451. begin
  452. s:=sectionattrs_coff(atype);
  453. if (s<>'') then
  454. writer.AsmWrite(',"'+s+'"');
  455. end
  456. else if target_info.system in systems_aix then
  457. begin
  458. s:=sectionalignment_aix(atype,secalign);
  459. if s<>'' then
  460. writer.AsmWrite(','+s);
  461. end;
  462. end;
  463. writer.AsmLn;
  464. LastSecType:=atype;
  465. end;
  466. procedure TGNUAssembler.WriteDecodedUleb128(a: qword);
  467. var
  468. i,len : longint;
  469. buf : array[0..63] of byte;
  470. begin
  471. len:=EncodeUleb128(a,buf);
  472. for i:=0 to len-1 do
  473. begin
  474. if (i > 0) then
  475. writer.AsmWrite(',');
  476. writer.AsmWrite(tostr(buf[i]));
  477. end;
  478. end;
  479. procedure TGNUAssembler.WriteDecodedSleb128(a: int64);
  480. var
  481. i,len : longint;
  482. buf : array[0..255] of byte;
  483. begin
  484. len:=EncodeSleb128(a,buf);
  485. for i:=0 to len-1 do
  486. begin
  487. if (i > 0) then
  488. writer.AsmWrite(',');
  489. writer.AsmWrite(tostr(buf[i]));
  490. end;
  491. end;
  492. procedure TGNUAssembler.WriteTree(p:TAsmList);
  493. function needsObject(hp : tai_symbol) : boolean;
  494. begin
  495. needsObject :=
  496. (
  497. assigned(hp.next) and
  498. (tai(hp.next).typ in [ait_const,ait_datablock,ait_realconst])
  499. ) or
  500. (hp.sym.typ=AT_DATA);
  501. end;
  502. procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint;lasthp:tai);
  503. var
  504. i: longint;
  505. {$ifdef m68k}
  506. instr : string;
  507. {$endif}
  508. begin
  509. last_align:=alignment;
  510. if alignment>1 then
  511. begin
  512. if not(target_info.system in (systems_darwin+systems_aix)) then
  513. begin
  514. {$ifdef m68k}
  515. if not use_op and (lastsectype=sec_code) then
  516. begin
  517. if not ispowerof2(alignment,i) then
  518. internalerror(2014022201);
  519. { the Coldfire manual suggests the TBF instruction for
  520. alignments, but somehow QEMU does not interpret that
  521. correctly... }
  522. {if current_settings.cputype in cpu_coldfire then
  523. instr:='0x51fc'
  524. else}
  525. instr:='0x4e71';
  526. writer.AsmWrite(#9'.balignw '+tostr(alignment)+','+instr);
  527. end
  528. else
  529. begin
  530. {$endif m68k}
  531. writer.AsmWrite(#9'.balign '+tostr(alignment));
  532. if use_op then
  533. writer.AsmWrite(','+tostr(fillop))
  534. {$ifdef x86}
  535. { force NOP as alignment op code }
  536. else if (LastSecType=sec_code) and (asminfo^.id<>as_solaris_as) then
  537. writer.AsmWrite(',0x90');
  538. {$endif x86}
  539. {$ifdef m68k}
  540. end;
  541. {$endif m68k}
  542. end
  543. else
  544. begin
  545. { darwin and aix as only support .align }
  546. if not ispowerof2(alignment,i) then
  547. internalerror(2003010305);
  548. writer.AsmWrite(#9'.align '+tostr(i));
  549. last_align:=i;
  550. end;
  551. writer.AsmLn;
  552. end;
  553. end;
  554. var
  555. ch : char;
  556. lasthp,
  557. hp : tai;
  558. constdef : taiconst_type;
  559. s,t : string;
  560. i,pos,l : longint;
  561. InlineLevel : cardinal;
  562. last_align : longint;
  563. do_line : boolean;
  564. sepChar : char;
  565. replaceforbidden: boolean;
  566. begin
  567. if not assigned(p) then
  568. exit;
  569. replaceforbidden:=asminfo^.dollarsign<>'$';
  570. last_align := 2;
  571. InlineLevel:=0;
  572. { lineinfo is only needed for al_procedures (PFV) }
  573. do_line:=(cs_asm_source in current_settings.globalswitches) or
  574. ((cs_lineinfo in current_settings.moduleswitches)
  575. and (p=current_asmdata.asmlists[al_procedures]));
  576. lasthp:=nil;
  577. hp:=tai(p.first);
  578. while assigned(hp) do
  579. begin
  580. prefetch(pointer(hp.next)^);
  581. if not(hp.typ in SkipLineInfo) then
  582. begin
  583. current_filepos:=tailineinfo(hp).fileinfo;
  584. { no line info for inlined code }
  585. if do_line and (inlinelevel=0) then
  586. WriteSourceLine(hp as tailineinfo);
  587. end;
  588. case hp.typ of
  589. ait_comment :
  590. Begin
  591. writer.AsmWrite(asminfo^.comment);
  592. writer.AsmWritePChar(tai_comment(hp).str);
  593. writer.AsmLn;
  594. End;
  595. ait_regalloc :
  596. begin
  597. if (cs_asm_regalloc in current_settings.globalswitches) then
  598. begin
  599. writer.AsmWrite(#9+asminfo^.comment+'Register ');
  600. repeat
  601. writer.AsmWrite(std_regname(Tai_regalloc(hp).reg));
  602. if (hp.next=nil) or
  603. (tai(hp.next).typ<>ait_regalloc) or
  604. (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
  605. break;
  606. hp:=tai(hp.next);
  607. writer.AsmWrite(',');
  608. until false;
  609. writer.AsmWrite(' ');
  610. writer.AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
  611. end;
  612. end;
  613. ait_tempalloc :
  614. begin
  615. if (cs_asm_tempalloc in current_settings.globalswitches) then
  616. WriteTempalloc(tai_tempalloc(hp));
  617. end;
  618. ait_align :
  619. begin
  620. doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align,lasthp);
  621. end;
  622. ait_section :
  623. begin
  624. if tai_section(hp).sectype<>sec_none then
  625. if replaceforbidden then
  626. WriteSection(tai_section(hp).sectype,ReplaceForbiddenAsmSymbolChars(tai_section(hp).name^),tai_section(hp).secorder,tai_section(hp).secalign)
  627. else
  628. WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder,tai_section(hp).secalign)
  629. else
  630. begin
  631. {$ifdef EXTDEBUG}
  632. writer.AsmWrite(asminfo^.comment);
  633. writer.AsmWriteln(' sec_none');
  634. {$endif EXTDEBUG}
  635. end;
  636. end;
  637. ait_datablock :
  638. begin
  639. if (target_info.system in systems_darwin) then
  640. begin
  641. { On Mac OS X you can't have common symbols in a shared library
  642. since those are in the TEXT section and the text section is
  643. read-only in shared libraries (so it can be shared among different
  644. processes). The alternate code creates some kind of common symbols
  645. in the data segment.
  646. }
  647. if tai_datablock(hp).is_global then
  648. begin
  649. writer.AsmWrite('.globl ');
  650. writer.AsmWriteln(tai_datablock(hp).sym.name);
  651. writer.AsmWriteln('.data');
  652. writer.AsmWrite('.zerofill __DATA, __common, ');
  653. writer.AsmWrite(tai_datablock(hp).sym.name);
  654. writer.AsmWriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
  655. if not(LastSecType in [sec_data,sec_none]) then
  656. writesection(LastSecType,'',secorder_default,1 shl last_align);
  657. end
  658. else
  659. begin
  660. writer.AsmWrite(#9'.lcomm'#9);
  661. writer.AsmWrite(tai_datablock(hp).sym.name);
  662. writer.AsmWrite(','+tostr(tai_datablock(hp).size));
  663. writer.AsmWrite(','+tostr(last_align));
  664. writer.AsmLn;
  665. end;
  666. end
  667. else if target_info.system in systems_aix then
  668. begin
  669. if tai_datablock(hp).is_global then
  670. begin
  671. writer.AsmWrite(#9'.globl ');
  672. writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  673. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  674. writer.AsmWriteln(':');
  675. writer.AsmWrite(#9'.space ');
  676. writer.AsmWriteln(tostr(tai_datablock(hp).size));
  677. if not(LastSecType in [sec_data,sec_none]) then
  678. writesection(LastSecType,'',secorder_default,1 shl last_align);
  679. end
  680. else
  681. begin
  682. writer.AsmWrite(#9'.lcomm ');
  683. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  684. writer.AsmWrite(',');
  685. writer.AsmWrite(tostr(tai_datablock(hp).size)+',');
  686. writer.AsmWrite('_data.bss_,');
  687. writer.AsmWriteln(tostr(last_align));
  688. end;
  689. end
  690. else
  691. begin
  692. {$ifdef USE_COMM_IN_BSS}
  693. if writingpackages then
  694. begin
  695. { The .comm is required for COMMON symbols. These are used
  696. in the shared library loading. All the symbols declared in
  697. the .so file need to resolve to the data allocated in the main
  698. program (PFV) }
  699. if tai_datablock(hp).is_global then
  700. begin
  701. writer.AsmWrite(#9'.comm'#9);
  702. if replaceforbidden then
  703. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name))
  704. else
  705. writer.AsmWrite(tai_datablock(hp).sym.name);
  706. writer.AsmWrite(','+tostr(tai_datablock(hp).size));
  707. writer.AsmWrite(','+tostr(last_align));
  708. writer.AsmLn;
  709. end
  710. else
  711. begin
  712. writer.AsmWrite(#9'.lcomm'#9);
  713. if replaceforbidden then
  714. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  715. else
  716. writer.AsmWrite(tai_datablock(hp).sym.name);
  717. writer.AsmWrite(','+tostr(tai_datablock(hp).size));
  718. writer.AsmWrite(','+tostr(last_align));
  719. writer.AsmLn;
  720. end
  721. end
  722. else
  723. {$endif USE_COMM_IN_BSS}
  724. begin
  725. if Tai_datablock(hp).is_global then
  726. begin
  727. writer.AsmWrite(#9'.globl ');
  728. if replaceforbidden then
  729. writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
  730. else
  731. writer.AsmWriteln(Tai_datablock(hp).sym.name);
  732. end;
  733. if ((target_info.system <> system_arm_linux) and (target_info.system <> system_arm_android)) then
  734. sepChar := '@'
  735. else
  736. sepChar := '%';
  737. if replaceforbidden then
  738. begin
  739. if (tf_needs_symbol_type in target_info.flags) then
  740. writer.AsmWriteln(#9'.type '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+sepChar+'object');
  741. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  742. writer.AsmWriteln(#9'.size '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+tostr(Tai_datablock(hp).size));
  743. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
  744. end
  745. else
  746. begin
  747. if (tf_needs_symbol_type in target_info.flags) then
  748. writer.AsmWriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  749. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  750. writer.AsmWriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  751. writer.AsmWrite(Tai_datablock(hp).sym.name);
  752. end;
  753. writer.AsmWriteln(':');
  754. writer.AsmWriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  755. end;
  756. end;
  757. end;
  758. ait_const:
  759. begin
  760. constdef:=tai_const(hp).consttype;
  761. case constdef of
  762. {$ifndef cpu64bitaddr}
  763. aitconst_128bit :
  764. begin
  765. internalerror(200404291);
  766. end;
  767. aitconst_64bit :
  768. begin
  769. if assigned(tai_const(hp).sym) then
  770. internalerror(200404292);
  771. if not(target_info.system in systems_aix) then
  772. begin
  773. writer.AsmWrite(ait_const2str[aitconst_32bit]);
  774. if target_info.endian = endian_little then
  775. begin
  776. writer.AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  777. writer.AsmWrite(',');
  778. writer.AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  779. end
  780. else
  781. begin
  782. writer.AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  783. writer.AsmWrite(',');
  784. writer.AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  785. end;
  786. end
  787. else
  788. WriteAixIntConst(tai_const(hp));
  789. writer.AsmLn;
  790. end;
  791. {$endif cpu64bitaddr}
  792. aitconst_got:
  793. begin
  794. if tai_const(hp).symofs<>0 then
  795. InternalError(2015091401); // No symbol offset is allowed for GOT.
  796. writer.AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
  797. writer.AsmLn;
  798. end;
  799. aitconst_gotoff_symbol:
  800. begin
  801. if (tai_const(hp).sym=nil) then
  802. InternalError(2014022601);
  803. case target_info.cpu of
  804. cpu_mipseb,cpu_mipsel:
  805. begin
  806. writer.AsmWrite(#9'.gpword'#9);
  807. writer.AsmWrite(tai_const(hp).sym.name);
  808. end;
  809. cpu_i386:
  810. begin
  811. writer.AsmWrite(ait_const2str[aitconst_32bit]);
  812. writer.AsmWrite(tai_const(hp).sym.name+'-_GLOBAL_OFFSET_TABLE_');
  813. end;
  814. else
  815. InternalError(2014022602);
  816. end;
  817. if (tai_const(hp).value<>0) then
  818. writer.AsmWrite(tostr_with_plus(tai_const(hp).value));
  819. writer.AsmLn;
  820. end;
  821. aitconst_uleb128bit,
  822. aitconst_sleb128bit,
  823. {$ifdef cpu64bitaddr}
  824. aitconst_128bit,
  825. aitconst_64bit,
  826. {$endif cpu64bitaddr}
  827. aitconst_32bit,
  828. aitconst_16bit,
  829. aitconst_8bit,
  830. aitconst_rva_symbol,
  831. aitconst_secrel32_symbol,
  832. aitconst_darwin_dwarf_delta32,
  833. aitconst_darwin_dwarf_delta64,
  834. aitconst_half16bit,
  835. aitconst_gs,
  836. aitconst_16bit_unaligned,
  837. aitconst_32bit_unaligned,
  838. aitconst_64bit_unaligned:
  839. begin
  840. { the AIX assembler (and for compatibility, the GNU
  841. assembler when targeting AIX) automatically aligns
  842. .short/.long/.llong to a multiple of 2/4/8 bytes. We
  843. don't want that, since this may be data inside a packed
  844. record -> use .vbyte instead (byte stream of fixed
  845. length) }
  846. if (target_info.system in systems_aix) and
  847. (constdef in [aitconst_128bit,aitconst_64bit,aitconst_32bit,aitconst_16bit]) and
  848. not assigned(tai_const(hp).sym) then
  849. begin
  850. WriteAixIntConst(tai_const(hp));
  851. end
  852. else if (target_info.system in systems_darwin) and
  853. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  854. begin
  855. writer.AsmWrite(ait_const2str[aitconst_8bit]);
  856. case tai_const(hp).consttype of
  857. aitconst_uleb128bit:
  858. WriteDecodedUleb128(qword(tai_const(hp).value));
  859. aitconst_sleb128bit:
  860. WriteDecodedSleb128(int64(tai_const(hp).value));
  861. end
  862. end
  863. else
  864. begin
  865. if (constdef in ait_unaligned_consts) and
  866. (target_info.system in use_ua_sparc_systems) then
  867. writer.AsmWrite(ait_ua_sparc_const2str[constdef])
  868. else if (constdef in ait_unaligned_consts) and
  869. (target_info.system in use_ua_elf_systems) then
  870. writer.AsmWrite(ait_ua_elf_const2str[constdef])
  871. { we can also have unaligned pointers in packed record
  872. constants, which don't get translated into
  873. unaligned tai -> always use vbyte }
  874. else if target_info.system in systems_aix then
  875. writer.AsmWrite(#9'.vbyte'#9+tostr(tai_const(hp).size)+',')
  876. else if (asminfo^.id=as_solaris_as) then
  877. writer.AsmWrite(ait_solaris_const2str[constdef])
  878. else
  879. writer.AsmWrite(ait_const2str[constdef]);
  880. l:=0;
  881. t := '';
  882. repeat
  883. if assigned(tai_const(hp).sym) then
  884. begin
  885. if assigned(tai_const(hp).endsym) then
  886. begin
  887. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  888. begin
  889. s := NextSetLabel;
  890. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  891. end
  892. else
  893. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  894. end
  895. else
  896. s:=tai_const(hp).sym.name;
  897. if replaceforbidden then
  898. s:=ReplaceForbiddenAsmSymbolChars(s);
  899. if tai_const(hp).value<>0 then
  900. s:=s+tostr_with_plus(tai_const(hp).value);
  901. end
  902. else
  903. {$ifdef cpu64bitaddr}
  904. s:=tostr(tai_const(hp).value);
  905. {$else cpu64bitaddr}
  906. { 64 bit constants are already handled above in this case }
  907. s:=tostr(longint(tai_const(hp).value));
  908. {$endif cpu64bitaddr}
  909. if constdef = aitconst_half16bit then
  910. s:='('+s+')/2';
  911. if constdef = aitconst_gs then
  912. s:='gs('+s+')';
  913. writer.AsmWrite(s);
  914. inc(l,length(s));
  915. { Values with symbols are written on a single line to improve
  916. reading of the .s file (PFV) }
  917. if assigned(tai_const(hp).sym) or
  918. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  919. (l>line_length) or
  920. (hp.next=nil) or
  921. (tai(hp.next).typ<>ait_const) or
  922. (tai_const(hp.next).consttype<>constdef) or
  923. assigned(tai_const(hp.next).sym) then
  924. break;
  925. hp:=tai(hp.next);
  926. writer.AsmWrite(',');
  927. until false;
  928. if (t <> '') then
  929. begin
  930. writer.AsmLn;
  931. writer.AsmWrite(t);
  932. end;
  933. end;
  934. writer.AsmLn;
  935. end;
  936. else
  937. internalerror(200704251);
  938. end;
  939. end;
  940. ait_realconst :
  941. begin
  942. WriteRealConstAsBytes(tai_realconst(hp),#9'.byte'#9,do_line);
  943. end;
  944. ait_string :
  945. begin
  946. pos:=0;
  947. if not(target_info.system in systems_aix) then
  948. begin
  949. for i:=1 to tai_string(hp).len do
  950. begin
  951. if pos=0 then
  952. begin
  953. writer.AsmWrite(#9'.ascii'#9'"');
  954. pos:=20;
  955. end;
  956. ch:=tai_string(hp).str[i-1];
  957. case ch of
  958. #0, {This can't be done by range, because a bug in FPC}
  959. #1..#31,
  960. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  961. '"' : s:='\"';
  962. '\' : s:='\\';
  963. else
  964. s:=ch;
  965. end;
  966. writer.AsmWrite(s);
  967. inc(pos,length(s));
  968. if (pos>line_length) or (i=tai_string(hp).len) then
  969. begin
  970. writer.AsmWriteLn('"');
  971. pos:=0;
  972. end;
  973. end;
  974. end
  975. else
  976. WriteAixStringConst(tai_string(hp));
  977. end;
  978. ait_label :
  979. begin
  980. if (tai_label(hp).labsym.is_used) then
  981. begin
  982. if (tai_label(hp).labsym.bind=AB_PRIVATE_EXTERN) then
  983. begin
  984. writer.AsmWrite(#9'.private_extern ');
  985. writer.AsmWriteln(tai_label(hp).labsym.name);
  986. end;
  987. if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
  988. begin
  989. {$ifdef arm}
  990. { do no change arm mode accidently, .globl seems to reset the mode }
  991. if GenerateThumbCode or GenerateThumb2Code then
  992. writer.AsmWriteln(#9'.thumb_func'#9);
  993. {$endif arm}
  994. writer.AsmWrite('.globl'#9);
  995. if replaceforbidden then
  996. writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
  997. else
  998. writer.AsmWriteLn(tai_label(hp).labsym.name);
  999. end;
  1000. if replaceforbidden then
  1001. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
  1002. else
  1003. writer.AsmWrite(tai_label(hp).labsym.name);
  1004. writer.AsmWriteLn(':');
  1005. end;
  1006. end;
  1007. ait_symbol :
  1008. begin
  1009. if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
  1010. begin
  1011. writer.AsmWrite(#9'.private_extern ');
  1012. if replaceforbidden then
  1013. writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1014. else
  1015. writer.AsmWriteln(tai_symbol(hp).sym.name);
  1016. end;
  1017. if (target_info.system=system_powerpc64_linux) and
  1018. (tai_symbol(hp).sym.typ=AT_FUNCTION) and
  1019. (cs_profile in current_settings.moduleswitches) then
  1020. writer.AsmWriteLn('.globl _mcount');
  1021. if tai_symbol(hp).is_global then
  1022. begin
  1023. writer.AsmWrite('.globl'#9);
  1024. if replaceforbidden then
  1025. writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1026. else
  1027. writer.AsmWriteln(tai_symbol(hp).sym.name);
  1028. end;
  1029. if (target_info.system=system_powerpc64_linux) and
  1030. use_dotted_functions and
  1031. (tai_symbol(hp).sym.typ=AT_FUNCTION) then
  1032. begin
  1033. writer.AsmWriteLn('.section ".opd", "aw"');
  1034. writer.AsmWriteLn('.align 3');
  1035. writer.AsmWriteLn(tai_symbol(hp).sym.name + ':');
  1036. writer.AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  1037. writer.AsmWriteLn('.previous');
  1038. writer.AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  1039. if (tai_symbol(hp).is_global) then
  1040. writer.AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  1041. writer.AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  1042. { the dotted name is the name of the actual function entry }
  1043. writer.AsmWrite('.');
  1044. end
  1045. else if (target_info.system in systems_aix) and
  1046. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  1047. begin
  1048. if target_info.system=system_powerpc_aix then
  1049. begin
  1050. s:=#9'.long .';
  1051. ch:='2';
  1052. end
  1053. else
  1054. begin
  1055. s:=#9'.llong .';
  1056. ch:='3';
  1057. end;
  1058. writer.AsmWriteLn(#9'.csect '+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+'[DS],'+ch);
  1059. writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+':');
  1060. writer.AsmWriteln(s+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+', TOC[tc0], 0');
  1061. writer.AsmWriteln(#9'.csect .text[PR]');
  1062. if (tai_symbol(hp).is_global) then
  1063. writer.AsmWriteLn('.globl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1064. else
  1065. writer.AsmWriteLn('.lglobl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name));
  1066. { the dotted name is the name of the actual function entry }
  1067. writer.AsmWrite('.');
  1068. end
  1069. else
  1070. begin
  1071. if ((target_info.system <> system_arm_linux) and (target_info.system <> system_arm_android)) then
  1072. sepChar := '@'
  1073. else
  1074. sepChar := '#';
  1075. if (tf_needs_symbol_type in target_info.flags) then
  1076. begin
  1077. writer.AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  1078. if (needsObject(tai_symbol(hp))) then
  1079. writer.AsmWriteLn(',' + sepChar + 'object')
  1080. else
  1081. writer.AsmWriteLn(',' + sepChar + 'function');
  1082. end;
  1083. end;
  1084. if replaceforbidden then
  1085. if not(tai_symbol(hp).has_value) then
  1086. writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + ':'))
  1087. else
  1088. writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value)))
  1089. else if not(tai_symbol(hp).has_value) then
  1090. writer.AsmWriteLn(tai_symbol(hp).sym.name + ':')
  1091. else
  1092. writer.AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
  1093. end;
  1094. ait_symbolpair:
  1095. begin
  1096. writer.AsmWrite(#9);
  1097. writer.AsmWrite(symbolpairkindstr[tai_symbolpair(hp).kind]);
  1098. writer.AsmWrite(' ');
  1099. if tai_symbolpair(hp).kind<>spk_localentry then
  1100. s:=', '
  1101. else
  1102. { the .localentry directive has to specify the size from the
  1103. start till here of the non-local entry code as second argument }
  1104. s:=', .-';
  1105. if replaceforbidden then
  1106. begin
  1107. { avoid string truncation }
  1108. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbolpair(hp).sym^)+s);
  1109. writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbolpair(hp).value^));
  1110. end
  1111. else
  1112. begin
  1113. { avoid string truncation }
  1114. writer.AsmWrite(tai_symbolpair(hp).sym^+s);
  1115. writer.AsmWriteLn(tai_symbolpair(hp).value^);
  1116. end;
  1117. end;
  1118. ait_symbol_end :
  1119. begin
  1120. if tf_needs_symbol_size in target_info.flags then
  1121. begin
  1122. s:=asminfo^.labelprefix+'e'+tostr(symendcount);
  1123. inc(symendcount);
  1124. writer.AsmWriteLn(s+':');
  1125. writer.AsmWrite(#9'.size'#9);
  1126. if (target_info.system=system_powerpc64_linux) and
  1127. use_dotted_functions and
  1128. (tai_symbol_end(hp).sym.typ=AT_FUNCTION) then
  1129. writer.AsmWrite('.');
  1130. if replaceforbidden then
  1131. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1132. else
  1133. writer.AsmWrite(tai_symbol_end(hp).sym.name);
  1134. writer.AsmWrite(', '+s+' - ');
  1135. if (target_info.system=system_powerpc64_linux) and
  1136. use_dotted_functions and
  1137. (tai_symbol_end(hp).sym.typ=AT_FUNCTION) then
  1138. writer.AsmWrite('.');
  1139. if replaceforbidden then
  1140. writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1141. else
  1142. writer.AsmWriteLn(tai_symbol_end(hp).sym.name);
  1143. end;
  1144. end;
  1145. ait_instruction :
  1146. begin
  1147. WriteInstruction(hp);
  1148. end;
  1149. ait_stab :
  1150. begin
  1151. if assigned(tai_stab(hp).str) then
  1152. begin
  1153. writer.AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  1154. writer.AsmWritePChar(tai_stab(hp).str);
  1155. writer.AsmLn;
  1156. end;
  1157. end;
  1158. ait_force_line,
  1159. ait_function_name :
  1160. begin
  1161. {$ifdef DEBUG_AGGAS}
  1162. WriteStr(s,hp.typ);
  1163. writer.AsmWriteLn('# '+s);
  1164. {$endif DEBUG_AGGAS}
  1165. end;
  1166. ait_cutobject :
  1167. begin
  1168. {$ifdef DEBUG_AGGAS}
  1169. writer.AsmWriteLn('# ait_cutobject');
  1170. {$endif DEBUG_AGGAS}
  1171. if SmartAsm then
  1172. begin
  1173. { only reset buffer if nothing has changed }
  1174. if not(writer.ClearIfEmpty) then
  1175. begin
  1176. writer.AsmClose;
  1177. DoAssemble;
  1178. writer.AsmCreate(tai_cutobject(hp).place);
  1179. end;
  1180. { avoid empty files }
  1181. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1182. begin
  1183. if tai(hp.next).typ=ait_section then
  1184. LastSecType:=tai_section(hp.next).sectype;
  1185. hp:=tai(hp.next);
  1186. end;
  1187. if LastSecType<>sec_none then
  1188. WriteSection(LastSecType,'',secorder_default,last_align);
  1189. writer.MarkEmpty;
  1190. end;
  1191. end;
  1192. ait_marker :
  1193. begin
  1194. {$ifdef DEBUG_AGGAS}
  1195. WriteStr(s,tai_marker(hp).Kind);
  1196. writer.AsmWriteLn('# ait_marker, kind: '+s);
  1197. {$endif DEBUG_AGGAS}
  1198. if tai_marker(hp).kind=mark_NoLineInfoStart then
  1199. inc(InlineLevel)
  1200. else if tai_marker(hp).kind=mark_NoLineInfoEnd then
  1201. dec(InlineLevel);
  1202. end;
  1203. ait_directive :
  1204. begin
  1205. WriteDirectiveName(tai_directive(hp).directive);
  1206. if tai_directive(hp).name <>'' then
  1207. begin
  1208. if replaceforbidden then
  1209. writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_directive(hp).name))
  1210. else
  1211. writer.AsmWrite(tai_directive(hp).name);
  1212. end;
  1213. writer.AsmLn;
  1214. end;
  1215. ait_seh_directive :
  1216. begin
  1217. {$ifndef DISABLE_WIN64_SEH}
  1218. writer.AsmWrite(sehdirectivestr[tai_seh_directive(hp).kind]);
  1219. case tai_seh_directive(hp).datatype of
  1220. sd_none:;
  1221. sd_string:
  1222. begin
  1223. writer.AsmWrite(' '+tai_seh_directive(hp).data.name^);
  1224. if (tai_seh_directive(hp).data.flags and 1)<>0 then
  1225. writer.AsmWrite(',@except');
  1226. if (tai_seh_directive(hp).data.flags and 2)<>0 then
  1227. writer.AsmWrite(',@unwind');
  1228. end;
  1229. sd_reg:
  1230. writer.AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg));
  1231. sd_offset:
  1232. writer.AsmWrite(' '+tostr(tai_seh_directive(hp).data.offset));
  1233. sd_regoffset:
  1234. writer.AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg)+', '+
  1235. tostr(tai_seh_directive(hp).data.offset));
  1236. end;
  1237. writer.AsmLn;
  1238. {$endif DISABLE_WIN64_SEH}
  1239. end;
  1240. ait_varloc:
  1241. begin
  1242. if tai_varloc(hp).newlocationhi<>NR_NO then
  1243. writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1244. std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
  1245. else
  1246. writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1247. std_regname(tai_varloc(hp).newlocation)));
  1248. writer.AsmLn;
  1249. end;
  1250. else
  1251. internalerror(2006012201);
  1252. end;
  1253. lasthp:=hp;
  1254. hp:=tai(hp.next);
  1255. end;
  1256. end;
  1257. procedure TGNUAssembler.WriteExtraHeader;
  1258. begin
  1259. end;
  1260. procedure TGNUAssembler.WriteExtraFooter;
  1261. begin
  1262. end;
  1263. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1264. begin
  1265. InstrWriter.WriteInstruction(hp);
  1266. end;
  1267. procedure TGNUAssembler.WriteWeakSymbolRef(s: tasmsymbol);
  1268. begin
  1269. writer.AsmWriteLn(#9'.weak '+s.name);
  1270. end;
  1271. procedure TGNUAssembler.WriteAixStringConst(hp: tai_string);
  1272. type
  1273. tterminationkind = (term_none,term_string,term_nostring);
  1274. var
  1275. i: longint;
  1276. pos: longint;
  1277. s: string;
  1278. ch: char;
  1279. instring: boolean;
  1280. procedure newstatement(terminationkind: tterminationkind);
  1281. begin
  1282. case terminationkind of
  1283. term_none: ;
  1284. term_string:
  1285. writer.AsmWriteLn('"');
  1286. term_nostring:
  1287. writer.AsmLn;
  1288. end;
  1289. writer.AsmWrite(#9'.byte'#9);
  1290. pos:=20;
  1291. instring:=false;
  1292. end;
  1293. begin
  1294. pos:=0;
  1295. instring:=false;
  1296. for i:=1 to hp.len do
  1297. begin
  1298. if pos=0 then
  1299. newstatement(term_none);
  1300. ch:=hp.str[i-1];
  1301. case ch of
  1302. #0..#31,
  1303. #127..#255 :
  1304. begin
  1305. if instring then
  1306. newstatement(term_string);
  1307. if pos=20 then
  1308. s:=tostr(ord(ch))
  1309. else
  1310. s:=', '+tostr(ord(ch))
  1311. end;
  1312. '"' :
  1313. if instring then
  1314. s:='""'
  1315. else
  1316. begin
  1317. if pos<>20 then
  1318. newstatement(term_nostring);
  1319. s:='"""';
  1320. instring:=true;
  1321. end;
  1322. else
  1323. if not instring then
  1324. begin
  1325. if (pos<>20) then
  1326. newstatement(term_nostring);
  1327. s:='"'+ch;
  1328. instring:=true;
  1329. end
  1330. else
  1331. s:=ch;
  1332. end;
  1333. writer.AsmWrite(s);
  1334. inc(pos,length(s));
  1335. if (pos>line_length) or (i=tai_string(hp).len) then
  1336. begin
  1337. if instring then
  1338. writer.AsmWriteLn('"')
  1339. else
  1340. writer.AsmLn;
  1341. pos:=0;
  1342. end;
  1343. end;
  1344. end;
  1345. procedure TGNUAssembler.WriteAixIntConst(hp: tai_const);
  1346. var
  1347. pos, size: longint;
  1348. begin
  1349. { only big endian AIX supported for now }
  1350. if target_info.endian<>endian_big then
  1351. internalerror(2012010401);
  1352. { limitation: can only write 4 bytes at a time }
  1353. pos:=0;
  1354. size:=tai_const(hp).size;
  1355. while pos<(size-4) do
  1356. begin
  1357. writer.AsmWrite(#9'.vbyte'#9'4, ');
  1358. writer.AsmWriteln(tostr(longint(tai_const(hp).value shr ((size-pos-4)*8))));
  1359. inc(pos,4);
  1360. end;
  1361. writer.AsmWrite(#9'.vbyte'#9);
  1362. writer.AsmWrite(tostr(size-pos));
  1363. writer.AsmWrite(', ');
  1364. case size-pos of
  1365. 1: writer.AsmWrite(tostr(byte(tai_const(hp).value)));
  1366. 2: writer.AsmWrite(tostr(word(tai_const(hp).value)));
  1367. 4: writer.AsmWrite(tostr(longint(tai_const(hp).value)));
  1368. else
  1369. internalerror(2012010402);
  1370. end;
  1371. end;
  1372. procedure TGNUAssembler.WriteUnalignedIntConst(hp: tai_const);
  1373. var
  1374. pos, size: longint;
  1375. begin
  1376. size:=tai_const(hp).size;
  1377. writer.AsmWrite(#9'.byte'#9);
  1378. if target_info.endian=endian_big then
  1379. begin
  1380. pos:=size-1;
  1381. while pos>=0 do
  1382. begin
  1383. writer.AsmWrite(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1384. dec(pos);
  1385. if pos>=0 then
  1386. writer.AsmWrite(', ')
  1387. else
  1388. writer.AsmLn;
  1389. end;
  1390. end
  1391. else
  1392. begin
  1393. pos:=0;
  1394. while pos<size do
  1395. begin
  1396. writer.AsmWriteln(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1397. inc(pos);
  1398. if pos<=size then
  1399. writer.AsmWrite(', ')
  1400. else
  1401. writer.AsmLn;
  1402. end;
  1403. end;
  1404. writer.AsmLn;
  1405. end;
  1406. procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
  1407. begin
  1408. writer.AsmWrite('.'+directivestr[dir]+' ');
  1409. end;
  1410. procedure TGNUAssembler.WriteAsmList;
  1411. var
  1412. n : string;
  1413. hal : tasmlisttype;
  1414. i: longint;
  1415. begin
  1416. {$ifdef EXTDEBUG}
  1417. if current_module.mainsource<>'' then
  1418. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource);
  1419. {$endif}
  1420. if current_module.mainsource<>'' then
  1421. n:=ExtractFileName(current_module.mainsource)
  1422. else
  1423. n:=InputFileName;
  1424. { gcc does not add it either for Darwin. Grep for
  1425. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1426. }
  1427. if not(target_info.system in systems_darwin) then
  1428. writer.AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1429. WriteExtraHeader;
  1430. writer.MarkEmpty;
  1431. symendcount:=0;
  1432. for hal:=low(TasmlistType) to high(TasmlistType) do
  1433. begin
  1434. if not (current_asmdata.asmlists[hal].empty) then
  1435. begin
  1436. writer.AsmWriteLn(asminfo^.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1437. writetree(current_asmdata.asmlists[hal]);
  1438. writer.AsmWriteLn(asminfo^.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1439. end;
  1440. end;
  1441. { add weak symbol markers }
  1442. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1443. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1444. WriteWeakSymbolRef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1445. if create_smartlink_sections and
  1446. (target_info.system in systems_darwin) then
  1447. writer.AsmWriteLn(#9'.subsections_via_symbols');
  1448. { "no executable stack" marker }
  1449. { TODO: used by OpenBSD/NetBSD as well? }
  1450. if (target_info.system in (systems_linux + systems_android + systems_freebsd + systems_dragonfly)) and
  1451. not(cs_executable_stack in current_settings.moduleswitches) then
  1452. begin
  1453. writer.AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1454. end;
  1455. writer.AsmLn;
  1456. WriteExtraFooter;
  1457. {$ifdef EXTDEBUG}
  1458. if current_module.mainsource<>'' then
  1459. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
  1460. {$endif EXTDEBUG}
  1461. end;
  1462. {****************************************************************************}
  1463. { Apple/GNU Assembler writer }
  1464. {****************************************************************************}
  1465. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1466. begin
  1467. if (target_info.system in systems_darwin) then
  1468. case atype of
  1469. sec_user:
  1470. begin
  1471. result:='.section '+aname;
  1472. exit;
  1473. end;
  1474. sec_bss:
  1475. { all bss (lcomm) symbols are automatically put in the right }
  1476. { place by using the lcomm assembler directive }
  1477. atype := sec_none;
  1478. sec_debug_frame,
  1479. sec_eh_frame:
  1480. begin
  1481. result := '.section __DWARF,__debug_info,regular,debug';
  1482. exit;
  1483. end;
  1484. sec_debug_line:
  1485. begin
  1486. result := '.section __DWARF,__debug_line,regular,debug';
  1487. exit;
  1488. end;
  1489. sec_debug_info:
  1490. begin
  1491. result := '.section __DWARF,__debug_info,regular,debug';
  1492. exit;
  1493. end;
  1494. sec_debug_abbrev:
  1495. begin
  1496. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1497. exit;
  1498. end;
  1499. sec_rodata:
  1500. begin
  1501. result := '.const_data';
  1502. exit;
  1503. end;
  1504. sec_rodata_norel:
  1505. begin
  1506. result := '.const';
  1507. exit;
  1508. end;
  1509. sec_fpc:
  1510. begin
  1511. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1512. exit;
  1513. end;
  1514. sec_code:
  1515. begin
  1516. if (aname='fpc_geteipasebx') or
  1517. (aname='fpc_geteipasecx') then
  1518. begin
  1519. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1520. #10'.private_extern '+aname;
  1521. exit;
  1522. end;
  1523. end;
  1524. sec_data_nonlazy:
  1525. begin
  1526. result:='.section __DATA, __nl_symbol_ptr,non_lazy_symbol_pointers';
  1527. exit;
  1528. end;
  1529. sec_data_lazy:
  1530. begin
  1531. result:='.section __DATA, __la_symbol_ptr,lazy_symbol_pointers';
  1532. exit;
  1533. end;
  1534. sec_init_func:
  1535. begin
  1536. result:='.section __DATA, __mod_init_func, mod_init_funcs';
  1537. exit;
  1538. end;
  1539. sec_term_func:
  1540. begin
  1541. result:='.section __DATA, __mod_term_func, mod_term_funcs';
  1542. exit;
  1543. end;
  1544. low(TObjCAsmSectionType)..high(TObjCAsmSectionType):
  1545. begin
  1546. result:='.section '+objc_section_name(atype);
  1547. exit
  1548. end;
  1549. end;
  1550. result := inherited sectionname(atype,aname,aorder);
  1551. end;
  1552. procedure TAppleGNUAssembler.WriteWeakSymbolRef(s: tasmsymbol);
  1553. begin
  1554. writer.AsmWriteLn(#9'.weak_reference '+s.name);
  1555. end;
  1556. procedure TAppleGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
  1557. begin
  1558. case dir of
  1559. asd_weak_reference:
  1560. writer.AsmWrite('.weak_reference ');
  1561. asd_weak_definition:
  1562. writer.AsmWrite('.weak_definition ');
  1563. else
  1564. inherited;
  1565. end;
  1566. end;
  1567. {****************************************************************************}
  1568. { a.out/GNU Assembler writer }
  1569. {****************************************************************************}
  1570. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1571. const
  1572. (* Translation table - replace unsupported section types with basic ones. *)
  1573. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1574. sec_none,
  1575. sec_none,
  1576. sec_code,
  1577. sec_data,
  1578. sec_data (* sec_rodata *),
  1579. sec_data (* sec_rodata_norel *),
  1580. sec_bss,
  1581. sec_data (* sec_threadvar *),
  1582. { used for wince exception handling }
  1583. sec_code (* sec_pdata *),
  1584. { used for darwin import stubs }
  1585. sec_code (* sec_stub *),
  1586. sec_data,(* sec_data_nonlazy *)
  1587. sec_data,(* sec_data_lazy *)
  1588. sec_data,(* sec_init_func *)
  1589. sec_data,(* sec_term_func *)
  1590. { stabs }
  1591. sec_stab,sec_stabstr,
  1592. { win32 }
  1593. sec_data (* sec_idata2 *),
  1594. sec_data (* sec_idata4 *),
  1595. sec_data (* sec_idata5 *),
  1596. sec_data (* sec_idata6 *),
  1597. sec_data (* sec_idata7 *),
  1598. sec_data (* sec_edata *),
  1599. { C++ exception handling unwinding (uses dwarf) }
  1600. sec_eh_frame,
  1601. { dwarf }
  1602. sec_debug_frame,
  1603. sec_debug_info,
  1604. sec_debug_line,
  1605. sec_debug_abbrev,
  1606. { ELF resources (+ references to stabs debug information sections) }
  1607. sec_code (* sec_fpc *),
  1608. { Table of contents section }
  1609. sec_code (* sec_toc *),
  1610. sec_code (* sec_init *),
  1611. sec_code (* sec_fini *),
  1612. sec_none (* sec_objc_class *),
  1613. sec_none (* sec_objc_meta_class *),
  1614. sec_none (* sec_objc_cat_cls_meth *),
  1615. sec_none (* sec_objc_cat_inst_meth *),
  1616. sec_none (* sec_objc_protocol *),
  1617. sec_none (* sec_objc_string_object *),
  1618. sec_none (* sec_objc_cls_meth *),
  1619. sec_none (* sec_objc_inst_meth *),
  1620. sec_none (* sec_objc_cls_refs *),
  1621. sec_none (* sec_objc_message_refs *),
  1622. sec_none (* sec_objc_symbols *),
  1623. sec_none (* sec_objc_category *),
  1624. sec_none (* sec_objc_class_vars *),
  1625. sec_none (* sec_objc_instance_vars *),
  1626. sec_none (* sec_objc_module_info *),
  1627. sec_none (* sec_objc_class_names *),
  1628. sec_none (* sec_objc_meth_var_types *),
  1629. sec_none (* sec_objc_meth_var_names *),
  1630. sec_none (* sec_objc_selector_strs *),
  1631. sec_none (* sec_objc_protocol_ext *),
  1632. sec_none (* sec_objc_class_ext *),
  1633. sec_none (* sec_objc_property *),
  1634. sec_none (* sec_objc_image_info *),
  1635. sec_none (* sec_objc_cstring_object *),
  1636. sec_none (* sec_objc_sel_fixup *),
  1637. sec_none (* sec_objc_data *),
  1638. sec_none (* sec_objc_const *),
  1639. sec_none (* sec_objc_sup_refs *),
  1640. sec_none (* sec_data_coalesced *),
  1641. sec_none (* sec_objc_classlist *),
  1642. sec_none (* sec_objc_nlclasslist *),
  1643. sec_none (* sec_objc_catlist *),
  1644. sec_none (* sec_objc_nlcatlist *),
  1645. sec_none (* sec_objc_protlist *),
  1646. sec_none (* sec_stack *),
  1647. sec_none (* sec_heap *)
  1648. );
  1649. begin
  1650. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1651. end;
  1652. {****************************************************************************}
  1653. { Abstract Instruction Writer }
  1654. {****************************************************************************}
  1655. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1656. begin
  1657. inherited create;
  1658. owner := _owner;
  1659. end;
  1660. end.