aggas.pas 68 KB

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