aggas.pas 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868
  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. end;
  689. end
  690. else
  691. begin
  692. {$ifdef USE_COMM_IN_BSS}
  693. if writingpackages then
  694. begin
  695. { The .comm is required for COMMON symbols. These are used
  696. in the shared library loading. All the symbols declared in
  697. the .so file need to resolve to the data allocated in the main
  698. program (PFV) }
  699. if tai_datablock(hp).is_global then
  700. begin
  701. asmwrite(#9'.comm'#9);
  702. if replaceforbidden then
  703. asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name))
  704. else
  705. asmwrite(tai_datablock(hp).sym.name);
  706. asmwrite(','+tostr(tai_datablock(hp).size));
  707. asmwrite(','+tostr(last_align));
  708. asmln;
  709. end
  710. else
  711. begin
  712. asmwrite(#9'.lcomm'#9);
  713. if replaceforbidden then
  714. asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
  715. else
  716. asmwrite(tai_datablock(hp).sym.name);
  717. asmwrite(','+tostr(tai_datablock(hp).size));
  718. asmwrite(','+tostr(last_align));
  719. asmln;
  720. end
  721. end
  722. else
  723. {$endif USE_COMM_IN_BSS}
  724. begin
  725. if Tai_datablock(hp).is_global then
  726. begin
  727. asmwrite(#9'.globl ');
  728. if replaceforbidden then
  729. asmwriteln(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
  730. else
  731. asmwriteln(Tai_datablock(hp).sym.name);
  732. end;
  733. if ((target_info.system <> system_arm_linux) and (target_info.system <> system_arm_android)) then
  734. sepChar := '@'
  735. else
  736. sepChar := '%';
  737. if replaceforbidden then
  738. begin
  739. if (tf_needs_symbol_type in target_info.flags) then
  740. asmwriteln(#9'.type '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+sepChar+'object');
  741. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  742. asmwriteln(#9'.size '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+tostr(Tai_datablock(hp).size));
  743. asmwrite(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
  744. end
  745. else
  746. begin
  747. if (tf_needs_symbol_type in target_info.flags) then
  748. asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  749. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  750. asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  751. asmwrite(Tai_datablock(hp).sym.name);
  752. end;
  753. asmwriteln(':');
  754. asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  755. end;
  756. end;
  757. end;
  758. ait_const:
  759. begin
  760. constdef:=tai_const(hp).consttype;
  761. case constdef of
  762. {$ifndef cpu64bitaddr}
  763. aitconst_128bit :
  764. begin
  765. internalerror(200404291);
  766. end;
  767. aitconst_64bit :
  768. begin
  769. if assigned(tai_const(hp).sym) then
  770. internalerror(200404292);
  771. if not(target_info.system in systems_aix) then
  772. begin
  773. AsmWrite(ait_const2str[aitconst_32bit]);
  774. if target_info.endian = endian_little then
  775. begin
  776. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  777. AsmWrite(',');
  778. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  779. end
  780. else
  781. begin
  782. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  783. AsmWrite(',');
  784. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  785. end;
  786. end
  787. else
  788. WriteAixIntConst(tai_const(hp));
  789. AsmLn;
  790. end;
  791. {$endif cpu64bitaddr}
  792. aitconst_got:
  793. begin
  794. AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
  795. Asmln;
  796. end;
  797. aitconst_gotoff_symbol:
  798. begin
  799. if (tai_const(hp).sym=nil) then
  800. InternalError(2014022601);
  801. case target_info.cpu of
  802. cpu_mipseb,cpu_mipsel:
  803. begin
  804. AsmWrite(#9'.gpword'#9);
  805. AsmWrite(tai_const(hp).sym.name);
  806. end;
  807. cpu_i386:
  808. begin
  809. AsmWrite(ait_const2str[aitconst_32bit]);
  810. AsmWrite(tai_const(hp).sym.name);
  811. end;
  812. else
  813. InternalError(2014022602);
  814. end;
  815. if (tai_const(hp).value<>0) then
  816. AsmWrite(tostr_with_plus(tai_const(hp).value));
  817. Asmln;
  818. end;
  819. aitconst_uleb128bit,
  820. aitconst_sleb128bit,
  821. {$ifdef cpu64bitaddr}
  822. aitconst_128bit,
  823. aitconst_64bit,
  824. {$endif cpu64bitaddr}
  825. aitconst_32bit,
  826. aitconst_16bit,
  827. aitconst_8bit,
  828. aitconst_rva_symbol,
  829. aitconst_secrel32_symbol,
  830. aitconst_darwin_dwarf_delta32,
  831. aitconst_darwin_dwarf_delta64,
  832. aitconst_half16bit,
  833. aitconst_16bit_unaligned,
  834. aitconst_32bit_unaligned,
  835. aitconst_64bit_unaligned:
  836. begin
  837. { the AIX assembler (and for compatibility, the GNU
  838. assembler when targeting AIX) automatically aligns
  839. .short/.long/.llong to a multiple of 2/4/8 bytes. We
  840. don't want that, since this may be data inside a packed
  841. record -> use .vbyte instead (byte stream of fixed
  842. length) }
  843. if (target_info.system in systems_aix) and
  844. (constdef in [aitconst_128bit,aitconst_64bit,aitconst_32bit,aitconst_16bit]) and
  845. not assigned(tai_const(hp).sym) then
  846. begin
  847. WriteAixIntConst(tai_const(hp));
  848. end
  849. else if (target_info.system in systems_darwin) and
  850. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  851. begin
  852. AsmWrite(ait_const2str[aitconst_8bit]);
  853. case tai_const(hp).consttype of
  854. aitconst_uleb128bit:
  855. WriteDecodedUleb128(qword(tai_const(hp).value));
  856. aitconst_sleb128bit:
  857. WriteDecodedSleb128(int64(tai_const(hp).value));
  858. end
  859. end
  860. else
  861. begin
  862. if (constdef in ait_unaligned_consts) and
  863. (target_info.system in use_ua_sparc_systems) then
  864. AsmWrite(ait_ua_sparc_const2str[constdef])
  865. else if (constdef in ait_unaligned_consts) and
  866. (target_info.system in use_ua_alpha_systems) then
  867. AsmWrite(ait_ua_alpha_const2str[constdef])
  868. else if (constdef in ait_unaligned_consts) and
  869. (target_info.system in use_ua_elf_systems) then
  870. AsmWrite(ait_ua_elf_const2str[constdef])
  871. { we can also have unaligned pointers in packed record
  872. constants, which don't get translated into
  873. unaligned tai -> always use vbyte }
  874. else if target_info.system in systems_aix then
  875. AsmWrite(#9'.vbyte'#9+tostr(tai_const(hp).size)+',')
  876. else
  877. AsmWrite(ait_const2str[constdef]);
  878. l:=0;
  879. t := '';
  880. repeat
  881. if assigned(tai_const(hp).sym) then
  882. begin
  883. if assigned(tai_const(hp).endsym) then
  884. begin
  885. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  886. begin
  887. s := NextSetLabel;
  888. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  889. end
  890. else
  891. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  892. end
  893. else
  894. s:=tai_const(hp).sym.name;
  895. if replaceforbidden then
  896. s:=ReplaceForbiddenAsmSymbolChars(s);
  897. if tai_const(hp).value<>0 then
  898. s:=s+tostr_with_plus(tai_const(hp).value);
  899. end
  900. else
  901. {$ifdef cpu64bitaddr}
  902. s:=tostr(tai_const(hp).value);
  903. {$else cpu64bitaddr}
  904. { 64 bit constants are already handled above in this case }
  905. s:=tostr(longint(tai_const(hp).value));
  906. {$endif cpu64bitaddr}
  907. if constdef = aitconst_half16bit then
  908. s:='('+s+')/2';
  909. AsmWrite(s);
  910. inc(l,length(s));
  911. { Values with symbols are written on a single line to improve
  912. reading of the .s file (PFV) }
  913. if assigned(tai_const(hp).sym) or
  914. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  915. (l>line_length) or
  916. (hp.next=nil) or
  917. (tai(hp.next).typ<>ait_const) or
  918. (tai_const(hp.next).consttype<>constdef) or
  919. assigned(tai_const(hp.next).sym) then
  920. break;
  921. hp:=tai(hp.next);
  922. AsmWrite(',');
  923. until false;
  924. if (t <> '') then
  925. begin
  926. AsmLn;
  927. AsmWrite(t);
  928. end;
  929. end;
  930. AsmLn;
  931. end;
  932. else
  933. internalerror(200704251);
  934. end;
  935. end;
  936. ait_realconst :
  937. begin
  938. WriteRealConstAsBytes(tai_realconst(hp),#9'.byte'#9,do_line);
  939. end;
  940. ait_string :
  941. begin
  942. pos:=0;
  943. if not(target_info.system in systems_aix) then
  944. begin
  945. for i:=1 to tai_string(hp).len do
  946. begin
  947. if pos=0 then
  948. begin
  949. AsmWrite(#9'.ascii'#9'"');
  950. pos:=20;
  951. end;
  952. ch:=tai_string(hp).str[i-1];
  953. case ch of
  954. #0, {This can't be done by range, because a bug in FPC}
  955. #1..#31,
  956. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  957. '"' : s:='\"';
  958. '\' : s:='\\';
  959. else
  960. s:=ch;
  961. end;
  962. AsmWrite(s);
  963. inc(pos,length(s));
  964. if (pos>line_length) or (i=tai_string(hp).len) then
  965. begin
  966. AsmWriteLn('"');
  967. pos:=0;
  968. end;
  969. end;
  970. end
  971. else
  972. WriteAixStringConst(tai_string(hp));
  973. end;
  974. ait_label :
  975. begin
  976. if (tai_label(hp).labsym.is_used) then
  977. begin
  978. if (tai_label(hp).labsym.bind=AB_PRIVATE_EXTERN) then
  979. begin
  980. AsmWrite(#9'.private_extern ');
  981. AsmWriteln(tai_label(hp).labsym.name);
  982. end;
  983. if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
  984. begin
  985. AsmWrite('.globl'#9);
  986. if replaceforbidden then
  987. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
  988. else
  989. AsmWriteLn(tai_label(hp).labsym.name);
  990. end;
  991. if replaceforbidden then
  992. AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
  993. else
  994. AsmWrite(tai_label(hp).labsym.name);
  995. AsmWriteLn(':');
  996. end;
  997. end;
  998. ait_symbol :
  999. begin
  1000. if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
  1001. begin
  1002. AsmWrite(#9'.private_extern ');
  1003. if replaceforbidden then
  1004. AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1005. else
  1006. AsmWriteln(tai_symbol(hp).sym.name);
  1007. end;
  1008. if (target_info.system = system_powerpc64_linux) and
  1009. (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
  1010. AsmWriteLn('.globl _mcount');
  1011. if tai_symbol(hp).is_global then
  1012. begin
  1013. AsmWrite('.globl'#9);
  1014. if replaceforbidden then
  1015. AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1016. else
  1017. AsmWriteln(tai_symbol(hp).sym.name);
  1018. end;
  1019. if (target_info.system = system_powerpc64_linux) and
  1020. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  1021. begin
  1022. AsmWriteLn('.section ".opd", "aw"');
  1023. AsmWriteLn('.align 3');
  1024. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  1025. AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  1026. AsmWriteLn('.previous');
  1027. AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  1028. if (tai_symbol(hp).is_global) then
  1029. AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  1030. AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  1031. { the dotted name is the name of the actual function entry }
  1032. AsmWrite('.');
  1033. end
  1034. else if (target_info.system in systems_aix) and
  1035. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  1036. begin
  1037. if target_info.system=system_powerpc_aix then
  1038. begin
  1039. s:=#9'.long .';
  1040. ch:='2';
  1041. end
  1042. else
  1043. begin
  1044. s:=#9'.llong .';
  1045. ch:='3';
  1046. end;
  1047. AsmWriteLn(#9'.csect '+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+'[DS],'+ch);
  1048. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+':');
  1049. AsmWriteln(s+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+', TOC[tc0], 0');
  1050. AsmWriteln(#9'.csect .text[PR]');
  1051. if (tai_symbol(hp).is_global) then
  1052. AsmWriteLn('.globl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
  1053. else
  1054. AsmWriteLn('.lglobl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name));
  1055. { the dotted name is the name of the actual function entry }
  1056. AsmWrite('.');
  1057. end
  1058. else
  1059. begin
  1060. if ((target_info.system <> system_arm_linux) and (target_info.system <> system_arm_android)) then
  1061. sepChar := '@'
  1062. else
  1063. sepChar := '#';
  1064. if (tf_needs_symbol_type in target_info.flags) then
  1065. begin
  1066. AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  1067. if (needsObject(tai_symbol(hp))) then
  1068. AsmWriteLn(',' + sepChar + 'object')
  1069. else
  1070. AsmWriteLn(',' + sepChar + 'function');
  1071. end;
  1072. end;
  1073. if replaceforbidden then
  1074. if not(tai_symbol(hp).has_value) then
  1075. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + ':'))
  1076. else
  1077. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value)))
  1078. else if not(tai_symbol(hp).has_value) then
  1079. AsmWriteLn(tai_symbol(hp).sym.name + ':')
  1080. else
  1081. AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
  1082. end;
  1083. {$ifdef arm}
  1084. ait_thumb_func:
  1085. begin
  1086. AsmWriteLn(#9'.thumb_func');
  1087. end;
  1088. ait_thumb_set:
  1089. begin
  1090. AsmWriteLn(#9'.thumb_set '+tai_thumb_set(hp).sym^+', '+tai_thumb_set(hp).value^);
  1091. end;
  1092. {$endif arm}
  1093. ait_set:
  1094. begin
  1095. if replaceforbidden then
  1096. AsmWriteLn(#9'.set '+ReplaceForbiddenAsmSymbolChars(tai_set(hp).sym^)+', '+ReplaceForbiddenAsmSymbolChars(tai_set(hp).value^))
  1097. else
  1098. AsmWriteLn(#9'.set '+tai_set(hp).sym^+', '+tai_set(hp).value^);
  1099. end;
  1100. ait_weak:
  1101. begin
  1102. if replaceforbidden then
  1103. AsmWriteLn(#9'.weak '+ReplaceForbiddenAsmSymbolChars(tai_weak(hp).sym^))
  1104. else
  1105. AsmWriteLn(#9'.weak '+tai_weak(hp).sym^);
  1106. end;
  1107. ait_symbol_end :
  1108. begin
  1109. if tf_needs_symbol_size in target_info.flags then
  1110. begin
  1111. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  1112. inc(symendcount);
  1113. AsmWriteLn(s+':');
  1114. AsmWrite(#9'.size'#9);
  1115. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1116. AsmWrite('.');
  1117. if replaceforbidden then
  1118. AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1119. else
  1120. AsmWrite(tai_symbol_end(hp).sym.name);
  1121. AsmWrite(', '+s+' - ');
  1122. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1123. AsmWrite('.');
  1124. if replaceforbidden then
  1125. AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
  1126. else
  1127. AsmWriteLn(tai_symbol_end(hp).sym.name);
  1128. end;
  1129. end;
  1130. ait_instruction :
  1131. begin
  1132. WriteInstruction(hp);
  1133. end;
  1134. ait_stab :
  1135. begin
  1136. if assigned(tai_stab(hp).str) then
  1137. begin
  1138. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  1139. AsmWritePChar(tai_stab(hp).str);
  1140. AsmLn;
  1141. end;
  1142. end;
  1143. ait_force_line,
  1144. ait_function_name :
  1145. ;
  1146. ait_cutobject :
  1147. begin
  1148. if SmartAsm then
  1149. begin
  1150. { only reset buffer if nothing has changed }
  1151. if AsmSize=AsmStartSize then
  1152. AsmClear
  1153. else
  1154. begin
  1155. AsmClose;
  1156. DoAssemble;
  1157. AsmCreate(tai_cutobject(hp).place);
  1158. end;
  1159. { avoid empty files }
  1160. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1161. begin
  1162. if tai(hp.next).typ=ait_section then
  1163. LastSecType:=tai_section(hp.next).sectype;
  1164. hp:=tai(hp.next);
  1165. end;
  1166. if LastSecType<>sec_none then
  1167. WriteSection(LastSecType,'',secorder_default,last_align);
  1168. AsmStartSize:=AsmSize;
  1169. end;
  1170. end;
  1171. ait_marker :
  1172. if tai_marker(hp).kind=mark_NoLineInfoStart then
  1173. inc(InlineLevel)
  1174. else if tai_marker(hp).kind=mark_NoLineInfoEnd then
  1175. dec(InlineLevel);
  1176. ait_directive :
  1177. begin
  1178. WriteDirectiveName(tai_directive(hp).directive);
  1179. if tai_directive(hp).name <>'' then
  1180. AsmWrite(tai_directive(hp).name);
  1181. AsmLn;
  1182. end;
  1183. ait_seh_directive :
  1184. begin
  1185. {$ifndef DISABLE_WIN64_SEH}
  1186. AsmWrite(sehdirectivestr[tai_seh_directive(hp).kind]);
  1187. case tai_seh_directive(hp).datatype of
  1188. sd_none:;
  1189. sd_string:
  1190. begin
  1191. AsmWrite(' '+tai_seh_directive(hp).data.name^);
  1192. if (tai_seh_directive(hp).data.flags and 1)<>0 then
  1193. AsmWrite(',@except');
  1194. if (tai_seh_directive(hp).data.flags and 2)<>0 then
  1195. AsmWrite(',@unwind');
  1196. end;
  1197. sd_reg:
  1198. AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg));
  1199. sd_offset:
  1200. AsmWrite(' '+tostr(tai_seh_directive(hp).data.offset));
  1201. sd_regoffset:
  1202. AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg)+', '+
  1203. tostr(tai_seh_directive(hp).data.offset));
  1204. end;
  1205. AsmLn;
  1206. {$endif DISABLE_WIN64_SEH}
  1207. end;
  1208. ait_varloc:
  1209. begin
  1210. if tai_varloc(hp).newlocationhi<>NR_NO then
  1211. AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1212. std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
  1213. else
  1214. AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
  1215. std_regname(tai_varloc(hp).newlocation)));
  1216. AsmLn;
  1217. end;
  1218. else
  1219. internalerror(2006012201);
  1220. end;
  1221. lasthp:=hp;
  1222. hp:=tai(hp.next);
  1223. end;
  1224. end;
  1225. procedure TGNUAssembler.WriteExtraHeader;
  1226. begin
  1227. end;
  1228. procedure TGNUAssembler.WriteExtraFooter;
  1229. begin
  1230. end;
  1231. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1232. begin
  1233. InstrWriter.WriteInstruction(hp);
  1234. end;
  1235. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1236. begin
  1237. AsmWriteLn(#9'.weak '+s.name);
  1238. end;
  1239. procedure TGNUAssembler.WriteAixStringConst(hp: tai_string);
  1240. type
  1241. tterminationkind = (term_none,term_string,term_nostring);
  1242. var
  1243. i: longint;
  1244. pos: longint;
  1245. s: string;
  1246. ch: char;
  1247. instring: boolean;
  1248. procedure newstatement(terminationkind: tterminationkind);
  1249. begin
  1250. case terminationkind of
  1251. term_none: ;
  1252. term_string:
  1253. AsmWriteLn('"');
  1254. term_nostring:
  1255. AsmLn;
  1256. end;
  1257. AsmWrite(#9'.byte'#9);
  1258. pos:=20;
  1259. instring:=false;
  1260. end;
  1261. begin
  1262. pos:=0;
  1263. instring:=false;
  1264. for i:=1 to hp.len do
  1265. begin
  1266. if pos=0 then
  1267. newstatement(term_none);
  1268. ch:=hp.str[i-1];
  1269. case ch of
  1270. #0..#31,
  1271. #127..#255 :
  1272. begin
  1273. if instring then
  1274. newstatement(term_string);
  1275. if pos=20 then
  1276. s:=tostr(ord(ch))
  1277. else
  1278. s:=', '+tostr(ord(ch))
  1279. end;
  1280. '"' :
  1281. if instring then
  1282. s:='""'
  1283. else
  1284. begin
  1285. if pos<>20 then
  1286. newstatement(term_nostring);
  1287. s:='"""';
  1288. instring:=true;
  1289. end;
  1290. else
  1291. if not instring then
  1292. begin
  1293. if (pos<>20) then
  1294. newstatement(term_nostring);
  1295. s:='"'+ch;
  1296. instring:=true;
  1297. end
  1298. else
  1299. s:=ch;
  1300. end;
  1301. AsmWrite(s);
  1302. inc(pos,length(s));
  1303. if (pos>line_length) or (i=tai_string(hp).len) then
  1304. begin
  1305. if instring then
  1306. AsmWriteLn('"')
  1307. else
  1308. AsmLn;
  1309. pos:=0;
  1310. end;
  1311. end;
  1312. end;
  1313. procedure TGNUAssembler.WriteAixIntConst(hp: tai_const);
  1314. var
  1315. pos, size: longint;
  1316. begin
  1317. { only big endian AIX supported for now }
  1318. if target_info.endian<>endian_big then
  1319. internalerror(2012010401);
  1320. { limitation: can only write 4 bytes at a time }
  1321. pos:=0;
  1322. size:=tai_const(hp).size;
  1323. while pos<(size-4) do
  1324. begin
  1325. AsmWrite(#9'.vbyte'#9'4, ');
  1326. AsmWriteln(tostr(longint(tai_const(hp).value shr ((size-pos-4)*8))));
  1327. inc(pos,4);
  1328. end;
  1329. AsmWrite(#9'.vbyte'#9);
  1330. AsmWrite(tostr(size-pos));
  1331. AsmWrite(', ');
  1332. case size-pos of
  1333. 1: AsmWrite(tostr(byte(tai_const(hp).value)));
  1334. 2: AsmWrite(tostr(word(tai_const(hp).value)));
  1335. 4: AsmWrite(tostr(longint(tai_const(hp).value)));
  1336. else
  1337. internalerror(2012010402);
  1338. end;
  1339. end;
  1340. procedure TGNUAssembler.WriteUnalignedIntConst(hp: tai_const);
  1341. var
  1342. pos, size: longint;
  1343. begin
  1344. size:=tai_const(hp).size;
  1345. AsmWrite(#9'.byte'#9);
  1346. if target_info.endian=endian_big then
  1347. begin
  1348. pos:=size-1;
  1349. while pos>=0 do
  1350. begin
  1351. AsmWrite(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1352. dec(pos);
  1353. if pos>=0 then
  1354. AsmWrite(', ')
  1355. else
  1356. AsmLn;
  1357. end;
  1358. end
  1359. else
  1360. begin
  1361. pos:=0;
  1362. while pos<size do
  1363. begin
  1364. AsmWriteln(tostr((tai_const(hp).value shr (pos*8)) and $ff));
  1365. inc(pos);
  1366. if pos<=size then
  1367. AsmWrite(', ')
  1368. else
  1369. AsmLn;
  1370. end;
  1371. end;
  1372. AsmLn;
  1373. end;
  1374. procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
  1375. begin
  1376. AsmWrite('.'+directivestr[dir]+' ');
  1377. end;
  1378. procedure TGNUAssembler.WriteAsmList;
  1379. var
  1380. n : string;
  1381. hal : tasmlisttype;
  1382. i: longint;
  1383. begin
  1384. {$ifdef EXTDEBUG}
  1385. if current_module.mainsource<>'' then
  1386. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource);
  1387. {$endif}
  1388. if current_module.mainsource<>'' then
  1389. n:=ExtractFileName(current_module.mainsource)
  1390. else
  1391. n:=InputFileName;
  1392. { gcc does not add it either for Darwin. Grep for
  1393. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1394. }
  1395. if not(target_info.system in systems_darwin) then
  1396. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1397. WriteExtraHeader;
  1398. AsmStartSize:=AsmSize;
  1399. symendcount:=0;
  1400. for hal:=low(TasmlistType) to high(TasmlistType) do
  1401. begin
  1402. if not (current_asmdata.asmlists[hal].empty) then
  1403. begin
  1404. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1405. writetree(current_asmdata.asmlists[hal]);
  1406. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1407. end;
  1408. end;
  1409. { add weak symbol markers }
  1410. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1411. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1412. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1413. if create_smartlink_sections and
  1414. (target_info.system in systems_darwin) then
  1415. AsmWriteLn(#9'.subsections_via_symbols');
  1416. { "no executable stack" marker }
  1417. { TODO: used by OpenBSD/NetBSD as well? }
  1418. if (target_info.system in (systems_linux + systems_android + systems_freebsd)) and
  1419. not(cs_executable_stack in current_settings.moduleswitches) then
  1420. begin
  1421. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1422. end;
  1423. AsmLn;
  1424. WriteExtraFooter;
  1425. {$ifdef EXTDEBUG}
  1426. if current_module.mainsource<>'' then
  1427. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
  1428. {$endif EXTDEBUG}
  1429. end;
  1430. {****************************************************************************}
  1431. { Apple/GNU Assembler writer }
  1432. {****************************************************************************}
  1433. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1434. begin
  1435. if (target_info.system in systems_darwin) then
  1436. case atype of
  1437. sec_bss:
  1438. { all bss (lcomm) symbols are automatically put in the right }
  1439. { place by using the lcomm assembler directive }
  1440. atype := sec_none;
  1441. sec_debug_frame,
  1442. sec_eh_frame:
  1443. begin
  1444. result := '.section __DWARF,__debug_info,regular,debug';
  1445. exit;
  1446. end;
  1447. sec_debug_line:
  1448. begin
  1449. result := '.section __DWARF,__debug_line,regular,debug';
  1450. exit;
  1451. end;
  1452. sec_debug_info:
  1453. begin
  1454. result := '.section __DWARF,__debug_info,regular,debug';
  1455. exit;
  1456. end;
  1457. sec_debug_abbrev:
  1458. begin
  1459. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1460. exit;
  1461. end;
  1462. sec_rodata:
  1463. begin
  1464. result := '.const_data';
  1465. exit;
  1466. end;
  1467. sec_rodata_norel:
  1468. begin
  1469. result := '.const';
  1470. exit;
  1471. end;
  1472. sec_fpc:
  1473. begin
  1474. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1475. exit;
  1476. end;
  1477. sec_code:
  1478. begin
  1479. if (aname='fpc_geteipasebx') or
  1480. (aname='fpc_geteipasecx') then
  1481. begin
  1482. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1483. #10'.private_extern '+aname;
  1484. exit;
  1485. end;
  1486. end;
  1487. sec_data_nonlazy:
  1488. begin
  1489. result:='.section __DATA, __nl_symbol_ptr,non_lazy_symbol_pointers';
  1490. exit;
  1491. end;
  1492. sec_data_lazy:
  1493. begin
  1494. result:='.section __DATA, __la_symbol_ptr,lazy_symbol_pointers';
  1495. exit;
  1496. end;
  1497. sec_init_func:
  1498. begin
  1499. result:='.section __DATA, __mod_init_func, mod_init_funcs';
  1500. exit;
  1501. end;
  1502. sec_term_func:
  1503. begin
  1504. result:='.section __DATA, __mod_term_func, mod_term_funcs';
  1505. exit;
  1506. end;
  1507. sec_objc_protocol_ext:
  1508. begin
  1509. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1510. exit;
  1511. end;
  1512. sec_objc_class_ext:
  1513. begin
  1514. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1515. exit;
  1516. end;
  1517. sec_objc_property:
  1518. begin
  1519. result:='.section __OBJC, __property, regular, no_dead_strip';
  1520. exit;
  1521. end;
  1522. sec_objc_image_info:
  1523. begin
  1524. if (target_info.system in systems_objc_nfabi) then
  1525. result:='.section __DATA,__objc_imageinfo,regular,no_dead_strip'
  1526. else
  1527. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1528. exit;
  1529. end;
  1530. sec_objc_cstring_object:
  1531. begin
  1532. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1533. exit;
  1534. end;
  1535. sec_objc_sel_fixup:
  1536. begin
  1537. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1538. exit;
  1539. end;
  1540. sec_objc_message_refs:
  1541. begin
  1542. if (target_info.system in systems_objc_nfabi) then
  1543. begin
  1544. result:='.section __DATA, __objc_selrefs, literal_pointers, no_dead_strip';
  1545. exit;
  1546. end;
  1547. end;
  1548. sec_objc_cls_refs:
  1549. begin
  1550. if (target_info.system in systems_objc_nfabi) then
  1551. begin
  1552. result:='.section __DATA, __objc_clsrefs, regular, no_dead_strip';
  1553. exit;
  1554. end;
  1555. end;
  1556. sec_objc_meth_var_types:
  1557. begin
  1558. if (target_info.system in systems_objc_nfabi) then
  1559. begin
  1560. result:='.section __TEXT,__objc_methtype,cstring_literals';
  1561. exit
  1562. end;
  1563. end;
  1564. sec_objc_meth_var_names:
  1565. begin
  1566. if (target_info.system in systems_objc_nfabi) then
  1567. begin
  1568. result:='.section __TEXT,__objc_methname,cstring_literals';
  1569. exit
  1570. end;
  1571. end;
  1572. sec_objc_class_names:
  1573. begin
  1574. if (target_info.system in systems_objc_nfabi) then
  1575. begin
  1576. result:='.section __TEXT,__objc_classname,cstring_literals';
  1577. exit
  1578. end;
  1579. end;
  1580. sec_objc_inst_meth,
  1581. sec_objc_cls_meth,
  1582. sec_objc_cat_inst_meth,
  1583. sec_objc_cat_cls_meth:
  1584. begin
  1585. if (target_info.system in systems_objc_nfabi) then
  1586. begin
  1587. result:='.section __DATA, __objc_const';
  1588. exit;
  1589. end;
  1590. end;
  1591. sec_objc_meta_class,
  1592. sec_objc_class:
  1593. begin
  1594. if (target_info.system in systems_objc_nfabi) then
  1595. begin
  1596. result:='.section __DATA, __objc_data';
  1597. exit;
  1598. end;
  1599. end;
  1600. sec_objc_sup_refs:
  1601. begin
  1602. result:='.section __DATA, __objc_superrefs, regular, no_dead_strip';
  1603. exit
  1604. end;
  1605. sec_objc_classlist:
  1606. begin
  1607. result:='.section __DATA, __objc_classlist, regular, no_dead_strip';
  1608. exit
  1609. end;
  1610. sec_objc_nlclasslist:
  1611. begin
  1612. result:='.section __DATA, __objc_nlclasslist, regular, no_dead_strip';
  1613. exit
  1614. end;
  1615. sec_objc_catlist:
  1616. begin
  1617. result:='.section __DATA, __objc_catlist, regular, no_dead_strip';
  1618. exit
  1619. end;
  1620. sec_objc_nlcatlist:
  1621. begin
  1622. result:='.section __DATA, __objc_nlcatlist, regular, no_dead_strip';
  1623. exit
  1624. end;
  1625. sec_objc_protolist:
  1626. begin
  1627. result:='.section __DATA, __objc_protolist, coalesced, no_dead_strip';
  1628. exit;
  1629. end;
  1630. end;
  1631. result := inherited sectionname(atype,aname,aorder);
  1632. end;
  1633. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1634. begin
  1635. AsmWriteLn(#9'.weak_reference '+s.name);
  1636. end;
  1637. {****************************************************************************}
  1638. { a.out/GNU Assembler writer }
  1639. {****************************************************************************}
  1640. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1641. const
  1642. (* Translation table - replace unsupported section types with basic ones. *)
  1643. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1644. sec_none,
  1645. sec_none,
  1646. sec_code,
  1647. sec_data,
  1648. sec_data (* sec_rodata *),
  1649. sec_data (* sec_rodata_norel *),
  1650. sec_bss,
  1651. sec_data (* sec_threadvar *),
  1652. { used for wince exception handling }
  1653. sec_code (* sec_pdata *),
  1654. { used for darwin import stubs }
  1655. sec_code (* sec_stub *),
  1656. sec_data,(* sec_data_nonlazy *)
  1657. sec_data,(* sec_data_lazy *)
  1658. sec_data,(* sec_init_func *)
  1659. sec_data,(* sec_term_func *)
  1660. { stabs }
  1661. sec_stab,sec_stabstr,
  1662. { win32 }
  1663. sec_data (* sec_idata2 *),
  1664. sec_data (* sec_idata4 *),
  1665. sec_data (* sec_idata5 *),
  1666. sec_data (* sec_idata6 *),
  1667. sec_data (* sec_idata7 *),
  1668. sec_data (* sec_edata *),
  1669. { C++ exception handling unwinding (uses dwarf) }
  1670. sec_eh_frame,
  1671. { dwarf }
  1672. sec_debug_frame,
  1673. sec_debug_info,
  1674. sec_debug_line,
  1675. sec_debug_abbrev,
  1676. { ELF resources (+ references to stabs debug information sections) }
  1677. sec_code (* sec_fpc *),
  1678. { Table of contents section }
  1679. sec_code (* sec_toc *),
  1680. sec_code (* sec_init *),
  1681. sec_code (* sec_fini *),
  1682. sec_none (* sec_objc_class *),
  1683. sec_none (* sec_objc_meta_class *),
  1684. sec_none (* sec_objc_cat_cls_meth *),
  1685. sec_none (* sec_objc_cat_inst_meth *),
  1686. sec_none (* sec_objc_protocol *),
  1687. sec_none (* sec_objc_string_object *),
  1688. sec_none (* sec_objc_cls_meth *),
  1689. sec_none (* sec_objc_inst_meth *),
  1690. sec_none (* sec_objc_cls_refs *),
  1691. sec_none (* sec_objc_message_refs *),
  1692. sec_none (* sec_objc_symbols *),
  1693. sec_none (* sec_objc_category *),
  1694. sec_none (* sec_objc_class_vars *),
  1695. sec_none (* sec_objc_instance_vars *),
  1696. sec_none (* sec_objc_module_info *),
  1697. sec_none (* sec_objc_class_names *),
  1698. sec_none (* sec_objc_meth_var_types *),
  1699. sec_none (* sec_objc_meth_var_names *),
  1700. sec_none (* sec_objc_selector_strs *),
  1701. sec_none (* sec_objc_protocol_ext *),
  1702. sec_none (* sec_objc_class_ext *),
  1703. sec_none (* sec_objc_property *),
  1704. sec_none (* sec_objc_image_info *),
  1705. sec_none (* sec_objc_cstring_object *),
  1706. sec_none (* sec_objc_sel_fixup *),
  1707. sec_none (* sec_objc_data *),
  1708. sec_none (* sec_objc_const *),
  1709. sec_none (* sec_objc_sup_refs *),
  1710. sec_none (* sec_data_coalesced *),
  1711. sec_none (* sec_objc_classlist *),
  1712. sec_none (* sec_objc_nlclasslist *),
  1713. sec_none (* sec_objc_catlist *),
  1714. sec_none (* sec_objc_nlcatlist *),
  1715. sec_none (* sec_objc_protlist *),
  1716. sec_none (* sec_stack *),
  1717. sec_none (* sec_heap *)
  1718. );
  1719. begin
  1720. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1721. end;
  1722. {****************************************************************************}
  1723. { Abstract Instruction Writer }
  1724. {****************************************************************************}
  1725. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1726. begin
  1727. inherited create;
  1728. owner := _owner;
  1729. end;
  1730. end.