aggas.pas 70 KB

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