aggas.pas 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386
  1. {
  2. Copyright (c) 1998-2006 by the Free Pascal team
  3. This unit implements the generic part of the GNU assembler
  4. (v2.8 or later) writer
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. { Base unit for writing GNU assembler output.
  19. }
  20. unit aggas;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. cclasses,
  25. globtype,globals,
  26. aasmbase,aasmtai,aasmdata,aasmcpu,
  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. procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  38. procedure WriteExtraHeader;virtual;
  39. procedure WriteInstruction(hp: tai);
  40. procedure WriteWeakSymbolDef(s: tasmsymbol); virtual;
  41. public
  42. function MakeCmdLine: TCmdStr; override;
  43. procedure WriteTree(p:TAsmList);override;
  44. procedure WriteAsmList;override;
  45. destructor destroy; override;
  46. private
  47. setcount: longint;
  48. procedure WriteDecodedSleb128(a: int64);
  49. procedure WriteDecodedUleb128(a: qword);
  50. function NextSetLabel: string;
  51. protected
  52. InstrWriter: TCPUInstrWriter;
  53. end;
  54. {# This is the base class for writing instructions.
  55. The WriteInstruction() method must be overriden
  56. to write a single instruction to the assembler
  57. file.
  58. }
  59. TCPUInstrWriter = class
  60. constructor create(_owner: TGNUAssembler);
  61. procedure WriteInstruction(hp : tai); virtual; abstract;
  62. protected
  63. owner: TGNUAssembler;
  64. end;
  65. { TAppleGNUAssembler }
  66. TAppleGNUAssembler=class(TGNUAssembler)
  67. protected
  68. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  69. procedure WriteWeakSymbolDef(s: tasmsymbol); override;
  70. end;
  71. TAoutGNUAssembler=class(TGNUAssembler)
  72. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  73. end;
  74. implementation
  75. uses
  76. SysUtils,
  77. cutils,cfileutl,systems,
  78. fmodule,finput,verbose,
  79. itcpugas,cpubase
  80. ;
  81. const
  82. line_length = 70;
  83. var
  84. symendcount : longint;
  85. type
  86. {$ifdef cpuextended}
  87. t80bitarray = array[0..9] of byte;
  88. {$endif cpuextended}
  89. t64bitarray = array[0..7] of byte;
  90. t32bitarray = array[0..3] of byte;
  91. {****************************************************************************}
  92. { Support routines }
  93. {****************************************************************************}
  94. function fixline(s:string):string;
  95. {
  96. return s with all leading and ending spaces and tabs removed
  97. }
  98. var
  99. i,j,k : integer;
  100. begin
  101. i:=length(s);
  102. while (i>0) and (s[i] in [#9,' ']) do
  103. dec(i);
  104. j:=1;
  105. while (j<i) and (s[j] in [#9,' ']) do
  106. inc(j);
  107. for k:=j to i do
  108. if s[k] in [#0..#31,#127..#255] then
  109. s[k]:='.';
  110. fixline:=Copy(s,j,i-j+1);
  111. end;
  112. function single2str(d : single) : string;
  113. var
  114. hs : string;
  115. begin
  116. str(d,hs);
  117. { replace space with + }
  118. if hs[1]=' ' then
  119. hs[1]:='+';
  120. single2str:='0d'+hs
  121. end;
  122. function double2str(d : double) : string;
  123. var
  124. hs : string;
  125. begin
  126. str(d,hs);
  127. { replace space with + }
  128. if hs[1]=' ' then
  129. hs[1]:='+';
  130. double2str:='0d'+hs
  131. end;
  132. function extended2str(e : extended) : string;
  133. var
  134. hs : string;
  135. begin
  136. str(e,hs);
  137. { replace space with + }
  138. if hs[1]=' ' then
  139. hs[1]:='+';
  140. extended2str:='0d'+hs
  141. end;
  142. { convert floating point values }
  143. { to correct endian }
  144. procedure swap64bitarray(var t: t64bitarray);
  145. var
  146. b: byte;
  147. begin
  148. b:= t[7];
  149. t[7] := t[0];
  150. t[0] := b;
  151. b := t[6];
  152. t[6] := t[1];
  153. t[1] := b;
  154. b:= t[5];
  155. t[5] := t[2];
  156. t[2] := b;
  157. b:= t[4];
  158. t[4] := t[3];
  159. t[3] := b;
  160. end;
  161. procedure swap32bitarray(var t: t32bitarray);
  162. var
  163. b: byte;
  164. begin
  165. b:= t[1];
  166. t[1]:= t[2];
  167. t[2]:= b;
  168. b:= t[0];
  169. t[0]:= t[3];
  170. t[3]:= b;
  171. end;
  172. const
  173. ait_const2str : array[aitconst_128bit..aitconst_darwin_dwarf_delta32] of string[20]=(
  174. #9'.fixme128'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9,#9'.byte'#9,
  175. #9'.sleb128'#9,#9'.uleb128'#9,
  176. #9'.rva'#9,#9'.secrel32'#9,#9'.indirect_symbol'#9,#9'.quad'#9,#9'.long'#9
  177. );
  178. {****************************************************************************}
  179. { GNU Assembler writer }
  180. {****************************************************************************}
  181. destructor TGNUAssembler.Destroy;
  182. begin
  183. InstrWriter.free;
  184. inherited destroy;
  185. end;
  186. function TGNUAssembler.MakeCmdLine: TCmdStr;
  187. begin
  188. result := inherited MakeCmdLine;
  189. // MWE: disabled again. It generates dwarf info for the generated .s
  190. // files as well. This conflicts with the info we generate
  191. // if target_dbg.id = dbg_dwarf then
  192. // result := result + ' --gdwarf-2';
  193. end;
  194. function TGNUAssembler.NextSetLabel: string;
  195. begin
  196. inc(setcount);
  197. result := target_asm.labelprefix+'$set$'+tostr(setcount);
  198. end;
  199. function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  200. const
  201. secnames : array[TAsmSectiontype] of string[length('.objc_meth_var_types')] = ('',
  202. '.text',
  203. '.data',
  204. { why doesn't .rodata work? (FK) }
  205. { sometimes we have to create a data.rel.ro instead of .rodata, e.g. for }
  206. { vtables (and anything else containing relocations), otherwise those are }
  207. { not relocated properly on e.g. linux/ppc64. g++ generates there for a }
  208. { vtable for a class called Window: }
  209. { .section .data.rel.ro._ZTV6Window,"awG",@progbits,_ZTV6Window,comdat }
  210. { TODO: .data.ro not yet working}
  211. {$if defined(arm) or defined(powerpc)}
  212. '.rodata',
  213. {$else arm}
  214. '.data',
  215. {$endif arm}
  216. {$if defined(m68k)} { Amiga/m68k GNU AS doesn't seem to like .rodata (KB) }
  217. '.data',
  218. {$else}
  219. '.rodata',
  220. {$endif}
  221. '.bss',
  222. '.threadvar',
  223. '.pdata',
  224. '', { stubs }
  225. '.stab',
  226. '.stabstr',
  227. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  228. '.eh_frame',
  229. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  230. '.fpc',
  231. '.toc',
  232. '.init',
  233. '.fini',
  234. '.objc_class',
  235. '.objc_meta_class',
  236. '.objc_cat_cls_meth',
  237. '.objc_cat_inst_meth',
  238. '.objc_protocol',
  239. '.objc_string_object',
  240. '.objc_cls_meth',
  241. '.objc_inst_meth',
  242. '.objc_cls_refs',
  243. '.objc_message_refs',
  244. '.objc_symbols',
  245. '.objc_category',
  246. '.objc_class_vars',
  247. '.objc_instance_vars',
  248. '.objc_module_info',
  249. '.objc_class_names',
  250. '.objc_meth_var_types',
  251. '.objc_meth_var_names',
  252. '.objc_selector_strs',
  253. '.objc_protocol_ext',
  254. '.objc_class_ext',
  255. '.objc_property',
  256. '.objc_image_info',
  257. '.objc_cstring_object',
  258. '.objc_sel_fixup'
  259. );
  260. secnames_pic : array[TAsmSectiontype] of string[length('.objc_meth_var_types')] = ('',
  261. '.text',
  262. '.data.rel',
  263. '.data.rel',
  264. '.data.rel',
  265. '.bss',
  266. '.threadvar',
  267. '.pdata',
  268. '', { stubs }
  269. '.stab',
  270. '.stabstr',
  271. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  272. '.eh_frame',
  273. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  274. '.fpc',
  275. '.toc',
  276. '.init',
  277. '.fini',
  278. '.objc_class',
  279. '.objc_meta_class',
  280. '.objc_cat_cls_meth',
  281. '.objc_cat_inst_meth',
  282. '.objc_protocol',
  283. '.objc_string_object',
  284. '.objc_cls_meth',
  285. '.objc_inst_meth',
  286. '.objc_cls_refs',
  287. '.objc_message_refs',
  288. '.objc_symbols',
  289. '.objc_category',
  290. '.objc_class_vars',
  291. '.objc_instance_vars',
  292. '.objc_module_info',
  293. '.objc_class_names',
  294. '.objc_meth_var_types',
  295. '.objc_meth_var_names',
  296. '.objc_selector_strs',
  297. '.objc_protocol_ext',
  298. '.objc_class_ext',
  299. '.objc_property',
  300. '.objc_image_info',
  301. '.objc_cstring_object',
  302. '.objc_sel_fixup'
  303. );
  304. var
  305. sep : string[3];
  306. secname : string;
  307. begin
  308. if (cs_create_pic in current_settings.moduleswitches) and
  309. not(target_info.system in systems_darwin) then
  310. secname:=secnames_pic[atype]
  311. else
  312. secname:=secnames[atype];
  313. {$ifdef m68k}
  314. { old Amiga GNU AS doesn't support .section .fpc }
  315. if (atype=sec_fpc) and (target_info.system = system_m68k_amiga) then
  316. secname:=secnames[sec_data];
  317. {$endif}
  318. if (atype=sec_fpc) and (Copy(aname,1,3)='res') then
  319. begin
  320. result:=secname+'.'+aname;
  321. exit;
  322. end;
  323. if (atype=sec_threadvar) and
  324. (target_info.system=system_i386_win32) then
  325. secname:='.tls';
  326. { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
  327. Thus, data which normally goes into .rodata and .rodata_norel sections must
  328. end up in .data section }
  329. if (atype in [sec_rodata,sec_rodata_norel]) and
  330. (target_info.system=system_i386_go32v2) then
  331. secname:='.data';
  332. { For bss we need to set some flags that are target dependent,
  333. it is easier to disable it for smartlinking. It doesn't take up
  334. filespace }
  335. if not(target_info.system in systems_darwin) and
  336. create_smartlink_sections and
  337. (aname<>'') and
  338. (atype <> sec_toc) and
  339. (atype<>sec_bss) then
  340. begin
  341. case aorder of
  342. secorder_begin :
  343. sep:='.b_';
  344. secorder_end :
  345. sep:='.z_';
  346. else
  347. sep:='.n_';
  348. end;
  349. result:=secname+sep+aname
  350. end
  351. else
  352. result:=secname;
  353. end;
  354. procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  355. var
  356. s : string;
  357. begin
  358. AsmLn;
  359. case target_info.system of
  360. system_i386_OS2,
  361. system_i386_EMX,
  362. system_m68k_amiga, { amiga has old GNU AS (2.14), which blews up from .section (KB) }
  363. system_m68k_linux: ;
  364. system_powerpc_darwin,
  365. system_i386_darwin,
  366. system_powerpc64_darwin,
  367. system_x86_64_darwin,
  368. system_arm_darwin:
  369. begin
  370. if (atype = sec_stub) then
  371. AsmWrite('.section ');
  372. end
  373. else
  374. AsmWrite('.section ');
  375. end;
  376. s:=sectionname(atype,aname,aorder);
  377. AsmWrite(s);
  378. case atype of
  379. sec_fpc :
  380. if aname = 'resptrs' then
  381. AsmWrite(', "a", @progbits');
  382. sec_stub :
  383. begin
  384. case target_info.system of
  385. { there are processor-independent shortcuts available }
  386. { for this, namely .symbol_stub and .picsymbol_stub, but }
  387. { they don't work and gcc doesn't use them either... }
  388. system_powerpc_darwin,
  389. system_powerpc64_darwin:
  390. if (cs_create_pic in current_settings.moduleswitches) then
  391. AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
  392. else
  393. AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
  394. system_i386_darwin:
  395. AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
  396. system_arm_darwin:
  397. if (cs_create_pic in current_settings.moduleswitches) then
  398. AsmWriteln('.section __TEXT,__picsymbolstub4,symbol_stubs,none,16')
  399. else
  400. AsmWriteln('.section __TEXT,__symbol_stub4,symbol_stubs,none,12')
  401. { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs }
  402. else
  403. internalerror(2006031101);
  404. end;
  405. end;
  406. end;
  407. AsmLn;
  408. LastSecType:=atype;
  409. end;
  410. procedure TGNUAssembler.WriteDecodedUleb128(a: qword);
  411. var
  412. i,len : longint;
  413. buf : array[0..63] of byte;
  414. begin
  415. len:=EncodeUleb128(a,buf);
  416. for i:=0 to len-1 do
  417. begin
  418. if (i > 0) then
  419. AsmWrite(',');
  420. AsmWrite(tostr(buf[i]));
  421. end;
  422. end;
  423. procedure TGNUAssembler.WriteDecodedSleb128(a: int64);
  424. var
  425. i,len : longint;
  426. buf : array[0..255] of byte;
  427. begin
  428. len:=EncodeSleb128(a,buf);
  429. for i:=0 to len-1 do
  430. begin
  431. if (i > 0) then
  432. AsmWrite(',');
  433. AsmWrite(tostr(buf[i]));
  434. end;
  435. end;
  436. procedure TGNUAssembler.WriteTree(p:TAsmList);
  437. function needsObject(hp : tai_symbol) : boolean;
  438. begin
  439. needsObject :=
  440. (
  441. assigned(hp.next) and
  442. (tai(hp.next).typ in [ait_const,ait_datablock,
  443. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit])
  444. ) or
  445. (hp.sym.typ=AT_DATA);
  446. end;
  447. var
  448. ch : char;
  449. hp : tai;
  450. hp1 : tailineinfo;
  451. constdef : taiconst_type;
  452. s,t : string;
  453. i,pos,l : longint;
  454. InlineLevel : longint;
  455. last_align : longint;
  456. co : comp;
  457. sin : single;
  458. d : double;
  459. {$ifdef cpuextended}
  460. e : extended;
  461. {$endif cpuextended}
  462. do_line : boolean;
  463. sepChar : char;
  464. begin
  465. if not assigned(p) then
  466. exit;
  467. last_align := 2;
  468. InlineLevel:=0;
  469. { lineinfo is only needed for al_procedures (PFV) }
  470. do_line:=(cs_asm_source in current_settings.globalswitches) or
  471. ((cs_lineinfo in current_settings.moduleswitches)
  472. and (p=current_asmdata.asmlists[al_procedures]));
  473. hp:=tai(p.first);
  474. while assigned(hp) do
  475. begin
  476. if not(hp.typ in SkipLineInfo) then
  477. begin
  478. hp1 := hp as tailineinfo;
  479. current_filepos:=hp1.fileinfo;
  480. { no line info for inlined code }
  481. if do_line and (inlinelevel=0) then
  482. begin
  483. { load infile }
  484. if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
  485. begin
  486. infile:=current_module.sourcefiles.get_file(hp1.fileinfo.fileindex);
  487. if assigned(infile) then
  488. begin
  489. { open only if needed !! }
  490. if (cs_asm_source in current_settings.globalswitches) then
  491. infile.open;
  492. end;
  493. { avoid unnecessary reopens of the same file !! }
  494. lastfileinfo.fileindex:=hp1.fileinfo.fileindex;
  495. { be sure to change line !! }
  496. lastfileinfo.line:=-1;
  497. end;
  498. { write source }
  499. if (cs_asm_source in current_settings.globalswitches) and
  500. assigned(infile) then
  501. begin
  502. if (infile<>lastinfile) then
  503. begin
  504. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  505. if assigned(lastinfile) then
  506. lastinfile.close;
  507. end;
  508. if (hp1.fileinfo.line<>lastfileinfo.line) and
  509. ((hp1.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  510. begin
  511. if (hp1.fileinfo.line<>0) and
  512. ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
  513. AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
  514. fixline(infile.GetLineStr(hp1.fileinfo.line)));
  515. { set it to a negative value !
  516. to make that is has been read already !! PM }
  517. if (infile.linebuf^[hp1.fileinfo.line]>=0) then
  518. infile.linebuf^[hp1.fileinfo.line]:=-infile.linebuf^[hp1.fileinfo.line]-1;
  519. end;
  520. end;
  521. lastfileinfo:=hp1.fileinfo;
  522. lastinfile:=infile;
  523. end;
  524. end;
  525. case hp.typ of
  526. ait_comment :
  527. Begin
  528. AsmWrite(target_asm.comment);
  529. AsmWritePChar(tai_comment(hp).str);
  530. AsmLn;
  531. End;
  532. ait_regalloc :
  533. begin
  534. if (cs_asm_regalloc in current_settings.globalswitches) then
  535. begin
  536. AsmWrite(#9+target_asm.comment+'Register ');
  537. repeat
  538. AsmWrite(std_regname(Tai_regalloc(hp).reg));
  539. if (hp.next=nil) or
  540. (tai(hp.next).typ<>ait_regalloc) or
  541. (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
  542. break;
  543. hp:=tai(hp.next);
  544. AsmWrite(',');
  545. until false;
  546. AsmWrite(' ');
  547. AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
  548. end;
  549. end;
  550. ait_tempalloc :
  551. begin
  552. if (cs_asm_tempalloc in current_settings.globalswitches) then
  553. begin
  554. {$ifdef EXTDEBUG}
  555. if assigned(tai_tempalloc(hp).problem) then
  556. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  557. tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
  558. else
  559. {$endif EXTDEBUG}
  560. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  561. tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
  562. end;
  563. end;
  564. ait_align :
  565. begin
  566. last_align := tai_align_abstract(hp).aligntype;
  567. if tai_align_abstract(hp).aligntype>1 then
  568. begin
  569. if not(target_info.system in systems_darwin) then
  570. begin
  571. AsmWrite(#9'.balign '+tostr(tai_align_abstract(hp).aligntype));
  572. if tai_align_abstract(hp).use_op then
  573. AsmWrite(','+tostr(tai_align_abstract(hp).fillop))
  574. {$ifdef x86}
  575. { force NOP as alignment op code }
  576. else if LastSecType=sec_code then
  577. AsmWrite(',0x90');
  578. {$endif x86}
  579. end
  580. else
  581. begin
  582. { darwin as only supports .align }
  583. if not ispowerof2(tai_align_abstract(hp).aligntype,i) then
  584. internalerror(2003010305);
  585. AsmWrite(#9'.align '+tostr(i));
  586. last_align := i;
  587. end;
  588. AsmLn;
  589. end;
  590. end;
  591. ait_section :
  592. begin
  593. if tai_section(hp).sectype<>sec_none then
  594. WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder)
  595. else
  596. begin
  597. {$ifdef EXTDEBUG}
  598. AsmWrite(target_asm.comment);
  599. AsmWriteln(' sec_none');
  600. {$endif EXTDEBUG}
  601. end;
  602. end;
  603. ait_datablock :
  604. begin
  605. if (target_info.system in systems_darwin) then
  606. begin
  607. { On Mac OS X you can't have common symbols in a shared library
  608. since those are in the TEXT section and the text section is
  609. read-only in shared libraries (so it can be shared among different
  610. processes). The alternate code creates some kind of common symbols
  611. in the data segment.
  612. }
  613. if tai_datablock(hp).is_global then
  614. begin
  615. asmwrite('.globl ');
  616. asmwriteln(tai_datablock(hp).sym.name);
  617. asmwriteln('.data');
  618. asmwrite('.zerofill __DATA, __common, ');
  619. asmwrite(tai_datablock(hp).sym.name);
  620. asmwriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
  621. if not(LastSecType in [sec_data,sec_none]) then
  622. writesection(LastSecType,'',secorder_default);
  623. end
  624. else
  625. begin
  626. asmwrite(#9'.lcomm'#9);
  627. asmwrite(tai_datablock(hp).sym.name);
  628. asmwrite(','+tostr(tai_datablock(hp).size));
  629. asmwrite(','+tostr(last_align));
  630. asmln;
  631. end;
  632. end
  633. else
  634. begin
  635. {$ifdef USE_COMM_IN_BSS}
  636. if writingpackages then
  637. begin
  638. { The .comm is required for COMMON symbols. These are used
  639. in the shared library loading. All the symbols declared in
  640. the .so file need to resolve to the data allocated in the main
  641. program (PFV) }
  642. if tai_datablock(hp).is_global then
  643. begin
  644. asmwrite(#9'.comm'#9);
  645. asmwrite(tai_datablock(hp).sym.name);
  646. asmwrite(','+tostr(tai_datablock(hp).size));
  647. asmwrite(','+tostr(last_align));
  648. asmln;
  649. end
  650. else
  651. begin
  652. asmwrite(#9'.lcomm'#9);
  653. asmwrite(tai_datablock(hp).sym.name);
  654. asmwrite(','+tostr(tai_datablock(hp).size));
  655. asmwrite(','+tostr(last_align));
  656. asmln;
  657. end
  658. end
  659. else
  660. {$endif USE_COMM_IN_BSS}
  661. begin
  662. if Tai_datablock(hp).is_global then
  663. begin
  664. asmwrite(#9'.globl ');
  665. asmwriteln(Tai_datablock(hp).sym.name);
  666. end;
  667. if (target_info.system <> system_arm_linux) then
  668. sepChar := '@'
  669. else
  670. sepChar := '%';
  671. if (tf_needs_symbol_type in target_info.flags) then
  672. asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  673. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  674. asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  675. asmwrite(Tai_datablock(hp).sym.name);
  676. asmwriteln(':');
  677. asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  678. end;
  679. end;
  680. end;
  681. ait_const:
  682. begin
  683. constdef:=tai_const(hp).consttype;
  684. case constdef of
  685. {$ifndef cpu64bitaddr}
  686. aitconst_128bit :
  687. begin
  688. internalerror(200404291);
  689. end;
  690. aitconst_64bit :
  691. begin
  692. if assigned(tai_const(hp).sym) then
  693. internalerror(200404292);
  694. AsmWrite(ait_const2str[aitconst_32bit]);
  695. if target_info.endian = endian_little then
  696. begin
  697. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  698. AsmWrite(',');
  699. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  700. end
  701. else
  702. begin
  703. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  704. AsmWrite(',');
  705. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  706. end;
  707. AsmLn;
  708. end;
  709. {$endif cpu64bitaddr}
  710. aitconst_uleb128bit,
  711. aitconst_sleb128bit,
  712. {$ifdef cpu64bitaddr}
  713. aitconst_128bit,
  714. aitconst_64bit,
  715. {$endif cpu64bitaddr}
  716. aitconst_32bit,
  717. aitconst_16bit,
  718. aitconst_8bit,
  719. aitconst_rva_symbol,
  720. aitconst_secrel32_symbol,
  721. aitconst_indirect_symbol,
  722. aitconst_darwin_dwarf_delta32,
  723. aitconst_darwin_dwarf_delta64:
  724. begin
  725. if (target_info.system in systems_darwin) and
  726. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  727. begin
  728. AsmWrite(ait_const2str[aitconst_8bit]);
  729. case tai_const(hp).consttype of
  730. aitconst_uleb128bit:
  731. WriteDecodedUleb128(qword(tai_const(hp).value));
  732. aitconst_sleb128bit:
  733. WriteDecodedSleb128(int64(tai_const(hp).value));
  734. end
  735. end
  736. else
  737. begin
  738. AsmWrite(ait_const2str[constdef]);
  739. l:=0;
  740. t := '';
  741. repeat
  742. if assigned(tai_const(hp).sym) then
  743. begin
  744. if assigned(tai_const(hp).endsym) then
  745. begin
  746. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  747. begin
  748. s := NextSetLabel;
  749. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  750. end
  751. else
  752. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  753. end
  754. else
  755. s:=tai_const(hp).sym.name;
  756. if tai_const(hp).value<>0 then
  757. s:=s+tostr_with_plus(tai_const(hp).value);
  758. end
  759. else
  760. s:=tostr(tai_const(hp).value);
  761. AsmWrite(s);
  762. inc(l,length(s));
  763. { Values with symbols are written on a single line to improve
  764. reading of the .s file (PFV) }
  765. if assigned(tai_const(hp).sym) or
  766. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  767. (l>line_length) or
  768. (hp.next=nil) or
  769. (tai(hp.next).typ<>ait_const) or
  770. (tai_const(hp.next).consttype<>constdef) or
  771. assigned(tai_const(hp.next).sym) then
  772. break;
  773. hp:=tai(hp.next);
  774. AsmWrite(',');
  775. until false;
  776. if (t <> '') then
  777. begin
  778. AsmLn;
  779. AsmWrite(t);
  780. end;
  781. end;
  782. AsmLn;
  783. end;
  784. else
  785. internalerror(200704251);
  786. end;
  787. end;
  788. { the "and defined(FPC_HAS_TYPE_EXTENDED)" isn't optimal but currently the only solution
  789. it prevents proper cross compilation to i386 though
  790. }
  791. {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
  792. ait_real_80bit :
  793. begin
  794. if do_line then
  795. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_real_80bit(hp).value));
  796. { Make sure e is a extended type, bestreal could be
  797. a different type (bestreal) !! (PFV) }
  798. e:=tai_real_80bit(hp).value;
  799. AsmWrite(#9'.byte'#9);
  800. for i:=0 to 9 do
  801. begin
  802. if i<>0 then
  803. AsmWrite(',');
  804. AsmWrite(tostr(t80bitarray(e)[i]));
  805. end;
  806. AsmLn;
  807. end;
  808. {$endif cpuextended}
  809. ait_real_64bit :
  810. begin
  811. if do_line then
  812. AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
  813. d:=tai_real_64bit(hp).value;
  814. { swap the values to correct endian if required }
  815. if source_info.endian <> target_info.endian then
  816. swap64bitarray(t64bitarray(d));
  817. AsmWrite(#9'.byte'#9);
  818. {$ifdef arm}
  819. if tai_real_64bit(hp).formatoptions=fo_hiloswapped then
  820. begin
  821. for i:=4 to 7 do
  822. begin
  823. if i<>4 then
  824. AsmWrite(',');
  825. AsmWrite(tostr(t64bitarray(d)[i]));
  826. end;
  827. for i:=0 to 3 do
  828. begin
  829. AsmWrite(',');
  830. AsmWrite(tostr(t64bitarray(d)[i]));
  831. end;
  832. end
  833. else
  834. {$endif arm}
  835. begin
  836. for i:=0 to 7 do
  837. begin
  838. if i<>0 then
  839. AsmWrite(',');
  840. AsmWrite(tostr(t64bitarray(d)[i]));
  841. end;
  842. end;
  843. AsmLn;
  844. end;
  845. ait_real_32bit :
  846. begin
  847. if do_line then
  848. AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
  849. sin:=tai_real_32bit(hp).value;
  850. { swap the values to correct endian if required }
  851. if source_info.endian <> target_info.endian then
  852. swap32bitarray(t32bitarray(sin));
  853. AsmWrite(#9'.byte'#9);
  854. for i:=0 to 3 do
  855. begin
  856. if i<>0 then
  857. AsmWrite(',');
  858. AsmWrite(tostr(t32bitarray(sin)[i]));
  859. end;
  860. AsmLn;
  861. end;
  862. ait_comp_64bit :
  863. begin
  864. if do_line then
  865. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_comp_64bit(hp).value));
  866. AsmWrite(#9'.byte'#9);
  867. co:=comp(tai_comp_64bit(hp).value);
  868. { swap the values to correct endian if required }
  869. if source_info.endian <> target_info.endian then
  870. swap64bitarray(t64bitarray(co));
  871. for i:=0 to 7 do
  872. begin
  873. if i<>0 then
  874. AsmWrite(',');
  875. AsmWrite(tostr(t64bitarray(co)[i]));
  876. end;
  877. AsmLn;
  878. end;
  879. ait_string :
  880. begin
  881. pos:=0;
  882. for i:=1 to tai_string(hp).len do
  883. begin
  884. if pos=0 then
  885. begin
  886. AsmWrite(#9'.ascii'#9'"');
  887. pos:=20;
  888. end;
  889. ch:=tai_string(hp).str[i-1];
  890. case ch of
  891. #0, {This can't be done by range, because a bug in FPC}
  892. #1..#31,
  893. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  894. '"' : s:='\"';
  895. '\' : s:='\\';
  896. else
  897. s:=ch;
  898. end;
  899. AsmWrite(s);
  900. inc(pos,length(s));
  901. if (pos>line_length) or (i=tai_string(hp).len) then
  902. begin
  903. AsmWriteLn('"');
  904. pos:=0;
  905. end;
  906. end;
  907. end;
  908. ait_label :
  909. begin
  910. if (tai_label(hp).labsym.is_used) then
  911. begin
  912. if tai_label(hp).labsym.bind=AB_GLOBAL then
  913. begin
  914. AsmWrite('.globl'#9);
  915. AsmWriteLn(tai_label(hp).labsym.name);
  916. end;
  917. AsmWrite(tai_label(hp).labsym.name);
  918. AsmWriteLn(':');
  919. end;
  920. end;
  921. ait_symbol :
  922. begin
  923. if (target_info.system = system_powerpc64_linux) and
  924. (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
  925. begin
  926. AsmWriteLn('.globl _mcount');
  927. end;
  928. if tai_symbol(hp).is_global then
  929. begin
  930. AsmWrite('.globl'#9);
  931. AsmWriteLn(tai_symbol(hp).sym.name);
  932. end;
  933. if (target_info.system = system_powerpc64_linux) and
  934. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  935. begin
  936. AsmWriteLn('.section ".opd", "aw"');
  937. AsmWriteLn('.align 3');
  938. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  939. AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  940. AsmWriteLn('.previous');
  941. AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  942. if (tai_symbol(hp).is_global) then
  943. AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  944. AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  945. { the dotted name is the name of the actual function entry }
  946. AsmWrite('.');
  947. end
  948. else
  949. begin
  950. if (target_info.system <> system_arm_linux) then
  951. sepChar := '@'
  952. else
  953. sepChar := '#';
  954. if (tf_needs_symbol_type in target_info.flags) then
  955. begin
  956. AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  957. if (needsObject(tai_symbol(hp))) then
  958. AsmWriteLn(',' + sepChar + 'object')
  959. else
  960. AsmWriteLn(',' + sepChar + 'function');
  961. end;
  962. end;
  963. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  964. end;
  965. ait_symbol_end :
  966. begin
  967. if tf_needs_symbol_size in target_info.flags then
  968. begin
  969. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  970. inc(symendcount);
  971. AsmWriteLn(s+':');
  972. AsmWrite(#9'.size'#9);
  973. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  974. AsmWrite('.');
  975. AsmWrite(tai_symbol_end(hp).sym.name);
  976. AsmWrite(', '+s+' - ');
  977. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  978. AsmWrite('.');
  979. AsmWriteLn(tai_symbol_end(hp).sym.name);
  980. end;
  981. end;
  982. ait_instruction :
  983. begin
  984. WriteInstruction(hp);
  985. end;
  986. ait_stab :
  987. begin
  988. if assigned(tai_stab(hp).str) then
  989. begin
  990. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  991. AsmWritePChar(tai_stab(hp).str);
  992. AsmLn;
  993. end;
  994. end;
  995. ait_force_line,
  996. ait_function_name : ;
  997. ait_cutobject :
  998. begin
  999. if SmartAsm then
  1000. begin
  1001. { only reset buffer if nothing has changed }
  1002. if AsmSize=AsmStartSize then
  1003. AsmClear
  1004. else
  1005. begin
  1006. AsmClose;
  1007. DoAssemble;
  1008. AsmCreate(tai_cutobject(hp).place);
  1009. end;
  1010. { avoid empty files }
  1011. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1012. begin
  1013. if tai(hp.next).typ=ait_section then
  1014. LastSecType:=tai_section(hp.next).sectype;
  1015. hp:=tai(hp.next);
  1016. end;
  1017. if LastSecType<>sec_none then
  1018. WriteSection(LastSecType,'',secorder_default);
  1019. AsmStartSize:=AsmSize;
  1020. end;
  1021. end;
  1022. ait_marker :
  1023. if tai_marker(hp).kind=mark_InlineStart then
  1024. inc(InlineLevel)
  1025. else if tai_marker(hp).kind=mark_InlineEnd then
  1026. dec(InlineLevel);
  1027. ait_directive :
  1028. begin
  1029. AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
  1030. if assigned(tai_directive(hp).name) then
  1031. AsmWrite(tai_directive(hp).name^);
  1032. AsmLn;
  1033. end;
  1034. else
  1035. internalerror(2006012201);
  1036. end;
  1037. hp:=tai(hp.next);
  1038. end;
  1039. end;
  1040. procedure TGNUAssembler.WriteExtraHeader;
  1041. begin
  1042. end;
  1043. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1044. begin
  1045. InstrWriter.WriteInstruction(hp);
  1046. end;
  1047. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1048. begin
  1049. AsmWriteLn(#9'.weak '+s.name);
  1050. end;
  1051. procedure TGNUAssembler.WriteAsmList;
  1052. var
  1053. n : string;
  1054. hal : tasmlisttype;
  1055. i: longint;
  1056. begin
  1057. {$ifdef EXTDEBUG}
  1058. if assigned(current_module.mainsource) then
  1059. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource^);
  1060. {$endif}
  1061. if assigned(current_module.mainsource) then
  1062. n:=ExtractFileName(current_module.mainsource^)
  1063. else
  1064. n:=InputFileName;
  1065. { gcc does not add it either for Darwin (and AIX). Grep for
  1066. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1067. }
  1068. if not(target_info.system in systems_darwin) then
  1069. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1070. WriteExtraHeader;
  1071. AsmStartSize:=AsmSize;
  1072. symendcount:=0;
  1073. for hal:=low(TasmlistType) to high(TasmlistType) do
  1074. begin
  1075. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1076. writetree(current_asmdata.asmlists[hal]);
  1077. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1078. end;
  1079. { add weak symbol markers }
  1080. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1081. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1082. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1083. if create_smartlink_sections and
  1084. (target_info.system in systems_darwin) then
  1085. AsmWriteLn(#9'.subsections_via_symbols');
  1086. { "no executable stack" marker for Linux }
  1087. if (target_info.system in system_linux) and
  1088. not(cs_executable_stack in current_settings.moduleswitches) then
  1089. begin
  1090. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1091. end;
  1092. AsmLn;
  1093. {$ifdef EXTDEBUG}
  1094. if assigned(current_module.mainsource) then
  1095. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource^);
  1096. {$endif EXTDEBUG}
  1097. end;
  1098. {****************************************************************************}
  1099. { Apple/GNU Assembler writer }
  1100. {****************************************************************************}
  1101. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1102. begin
  1103. if (target_info.system in systems_darwin) then
  1104. case atype of
  1105. sec_bss:
  1106. { all bss (lcomm) symbols are automatically put in the right }
  1107. { place by using the lcomm assembler directive }
  1108. atype := sec_none;
  1109. sec_debug_frame,
  1110. sec_eh_frame:
  1111. begin
  1112. result := '.section __DWARF,__debug_info,regular,debug';
  1113. exit;
  1114. end;
  1115. sec_debug_line:
  1116. begin
  1117. result := '.section __DWARF,__debug_line,regular,debug';
  1118. exit;
  1119. end;
  1120. sec_debug_info:
  1121. begin
  1122. result := '.section __DWARF,__debug_info,regular,debug';
  1123. exit;
  1124. end;
  1125. sec_debug_abbrev:
  1126. begin
  1127. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1128. exit;
  1129. end;
  1130. sec_rodata:
  1131. begin
  1132. result := '.const_data';
  1133. exit;
  1134. end;
  1135. sec_rodata_norel:
  1136. begin
  1137. result := '.const';
  1138. exit;
  1139. end;
  1140. sec_fpc:
  1141. begin
  1142. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1143. exit;
  1144. end;
  1145. sec_code:
  1146. begin
  1147. if (aname='fpc_geteipasebx') or
  1148. (aname='fpc_geteipasecx') then
  1149. begin
  1150. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1151. #10'.private_extern '+aname;
  1152. exit;
  1153. end;
  1154. end;
  1155. sec_objc_protocol_ext:
  1156. begin
  1157. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1158. exit;
  1159. end;
  1160. sec_objc_class_ext:
  1161. begin
  1162. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1163. exit;
  1164. end;
  1165. sec_objc_property:
  1166. begin
  1167. result:='.section __OBJC, __property, regular, no_dead_strip';
  1168. exit;
  1169. end;
  1170. sec_objc_image_info:
  1171. begin
  1172. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1173. exit;
  1174. end;
  1175. sec_objc_cstring_object:
  1176. begin
  1177. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1178. exit;
  1179. end;
  1180. sec_objc_sel_fixup:
  1181. begin
  1182. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1183. exit;
  1184. end;
  1185. end;
  1186. result := inherited sectionname(atype,aname,aorder);
  1187. end;
  1188. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1189. begin
  1190. AsmWriteLn(#9'.weak_reference '+s.name);
  1191. end;
  1192. {****************************************************************************}
  1193. { a.out/GNU Assembler writer }
  1194. {****************************************************************************}
  1195. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1196. const
  1197. (* Translation table - replace unsupported section types with basic ones. *)
  1198. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1199. sec_none,
  1200. sec_code,
  1201. sec_data,
  1202. sec_data (* sec_rodata *),
  1203. sec_data (* sec_rodata_norel *),
  1204. sec_bss,
  1205. sec_data (* sec_threadvar *),
  1206. { used for wince exception handling }
  1207. sec_code (* sec_pdata *),
  1208. { used for darwin import stubs }
  1209. sec_code (* sec_stub *),
  1210. { stabs }
  1211. sec_stab,sec_stabstr,
  1212. { win32 }
  1213. sec_data (* sec_idata2 *),
  1214. sec_data (* sec_idata4 *),
  1215. sec_data (* sec_idata5 *),
  1216. sec_data (* sec_idata6 *),
  1217. sec_data (* sec_idata7 *),
  1218. sec_data (* sec_edata *),
  1219. { C++ exception handling unwinding (uses dwarf) }
  1220. sec_eh_frame,
  1221. { dwarf }
  1222. sec_debug_frame,
  1223. sec_debug_info,
  1224. sec_debug_line,
  1225. sec_debug_abbrev,
  1226. { ELF resources (+ references to stabs debug information sections) }
  1227. sec_code (* sec_fpc *),
  1228. { Table of contents section }
  1229. sec_code (* sec_toc *),
  1230. sec_code (* sec_init *),
  1231. sec_code (* sec_fini *),
  1232. sec_none (* sec_objc_class *),
  1233. sec_none (* sec_objc_meta_class *),
  1234. sec_none (* sec_objc_cat_cls_meth *),
  1235. sec_none (* sec_objc_cat_inst_meth *),
  1236. sec_none (* sec_objc_protocol *),
  1237. sec_none (* sec_objc_string_object *),
  1238. sec_none (* sec_objc_cls_meth *),
  1239. sec_none (* sec_objc_inst_meth *),
  1240. sec_none (* sec_objc_cls_refs *),
  1241. sec_none (* sec_objc_message_refs *),
  1242. sec_none (* sec_objc_symbols *),
  1243. sec_none (* sec_objc_category *),
  1244. sec_none (* sec_objc_class_vars *),
  1245. sec_none (* sec_objc_instance_vars *),
  1246. sec_none (* sec_objc_module_info *),
  1247. sec_none (* sec_objc_class_names *),
  1248. sec_none (* sec_objc_meth_var_types *),
  1249. sec_none (* sec_objc_meth_var_names *),
  1250. sec_none (* sec_objc_selector_strs *),
  1251. sec_none (* sec_objc_protocol_ext *),
  1252. sec_none (* sec_objc_class_ext *),
  1253. sec_none (* sec_objc_property *),
  1254. sec_none (* sec_objc_image_info *),
  1255. sec_none (* sec_objc_cstring_object *),
  1256. sec_none (* sec_objc_sel_fixup *)
  1257. );
  1258. begin
  1259. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1260. end;
  1261. {****************************************************************************}
  1262. { Abstract Instruction Writer }
  1263. {****************************************************************************}
  1264. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1265. begin
  1266. inherited create;
  1267. owner := _owner;
  1268. end;
  1269. end.