aggas.pas 48 KB

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