aggas.pas 69 KB

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