aggas.pas 71 KB

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