aasmbase.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit implements an abstract asmoutput class for all processor types
  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. { @abstract(This unit implements an abstract asm output class for all processor types)
  19. This unit implements an abstract assembler output class for all processors, these
  20. are then overriden for each assembler writer to actually write the data in these
  21. classes to an assembler file.
  22. }
  23. unit aasmbase;
  24. {$i fpcdefs.inc}
  25. interface
  26. uses
  27. cutils,cclasses,
  28. globtype,globals,systems
  29. ;
  30. type
  31. TAsmSection = class;
  32. TAsmObjectData = class;
  33. TAsmsymbind=(AB_NONE,AB_EXTERNAL,AB_COMMON,AB_LOCAL,AB_GLOBAL);
  34. TAsmsymtype=(AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION);
  35. TAsmRelocationType = (RELOC_ABSOLUTE,RELOC_RELATIVE,RELOC_RVA);
  36. TAsmSectionType=(sec_none,
  37. sec_code,sec_data,sec_rodata,sec_bss,
  38. sec_common, { used for executable creation }
  39. sec_custom, { custom section, no prefix }
  40. { stabs }
  41. sec_stab,sec_stabstr,
  42. { win32 }
  43. sec_idata2,sec_idata4,sec_idata5,sec_idata6,sec_idata7,sec_edata,
  44. { C++ exception handling unwinding (uses dwarf) }
  45. sec_eh_frame,
  46. { dwarf }
  47. sec_debug_frame
  48. );
  49. TAsmSectionOption = (aso_alloconly,aso_executable);
  50. TAsmSectionOptions = set of TAsmSectionOption;
  51. TAsmSymbol = class(TNamedIndexItem)
  52. private
  53. { this need to be incremented with every symbol loading into the
  54. paasmoutput, thus in loadsym/loadref/const_symbol (PFV) }
  55. refs : longint;
  56. public
  57. defbind,
  58. currbind : TAsmsymbind;
  59. typ : TAsmsymtype;
  60. { the next fields are filled in the binary writer }
  61. section : TAsmSection;
  62. address,
  63. size : aint;
  64. { Alternate symbol which can be used for 'renaming' needed for
  65. inlining }
  66. altsymbol : tasmsymbol;
  67. { pointer to objectdata that is the owner of this symbol }
  68. owner : tasmobjectdata;
  69. { Is the symbol in the used list }
  70. inusedlist : boolean;
  71. { assembler pass label is set, used for detecting multiple labels }
  72. pass : byte;
  73. ppuidx : longint;
  74. constructor create(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  75. procedure reset;
  76. function is_used:boolean;
  77. procedure increfs;
  78. procedure decrefs;
  79. function getrefs: longint;
  80. procedure setaddress(_pass:byte;sec:TAsmSection;offset,len:aint);
  81. end;
  82. TAsmLabel = class(TAsmSymbol)
  83. { this is set by the tai_label.Init }
  84. is_set,
  85. { is the label only there for getting an address (e.g. for i/o }
  86. { checks -> true) or is it a jump target (false) }
  87. is_addr : boolean;
  88. labelnr : longint;
  89. constructor create(nr:longint);
  90. constructor createdata(const modulename:string;nr:longint);
  91. constructor createaddr(nr:longint);
  92. function getname:string;override;
  93. end;
  94. TAsmRelocation = class(TLinkedListItem)
  95. address,
  96. orgsize : aint; { original size of the symbol to relocate, required for COFF }
  97. symbol : TAsmSymbol;
  98. section : TAsmSection; { only used if symbol=nil }
  99. typ : TAsmRelocationType;
  100. constructor CreateSymbol(Aaddress:aint;s:Tasmsymbol;Atyp:TAsmRelocationType);
  101. constructor CreateSymbolSize(Aaddress:aint;s:Tasmsymbol;Aorgsize:aint;Atyp:TAsmRelocationType);
  102. constructor CreateSection(Aaddress:aint;sec:TAsmSection;Atyp:TAsmRelocationType);
  103. end;
  104. TAsmSection = class(TNamedIndexItem)
  105. owner : TAsmObjectData;
  106. secoptions : TAsmSectionOptions;
  107. sectype : TAsmSectionType;
  108. secsymidx : longint; { index for the section in symtab }
  109. addralign : longint; { alignment of the section }
  110. { size of the data and in the file }
  111. dataalignbytes : longint;
  112. data : TDynamicArray;
  113. datasize,
  114. datapos : aint;
  115. { size and position in memory }
  116. memsize,
  117. mempos : aint;
  118. { relocation }
  119. relocations : TLinkedList;
  120. constructor create(const Aname:string;Atype:TAsmSectionType;Aalign:longint;Aoptions:TAsmSectionOptions);virtual;
  121. destructor destroy;override;
  122. function write(const d;l:aint):aint;
  123. function writestr(const s:string):aint;
  124. procedure writealign(l:longint);
  125. function aligneddatasize:aint;
  126. procedure setdatapos(var dpos:aint);
  127. procedure alignsection;
  128. procedure alloc(l:aint);
  129. procedure addsymreloc(ofs:aint;p:tasmsymbol;relative:TAsmRelocationType);
  130. procedure addsectionreloc(ofs:aint;sec:TAsmSection;relative:TAsmRelocationType);
  131. procedure fixuprelocs;virtual;
  132. end;
  133. TAsmSectionClass = class of TAsmSection;
  134. TAsmObjectData = class(TLinkedListItem)
  135. private
  136. FName : string{$ifndef VER1_9_4}[80]{$endif};
  137. FCurrSec : TAsmSection;
  138. FSects : TDictionary;
  139. FCAsmSection : TAsmSectionClass;
  140. { Symbols that will be defined in this object file }
  141. FSymbols : TIndexArray;
  142. { Special info sections that are written to during object generation }
  143. FStabsRecSize : longint;
  144. FStabsSec,
  145. FStabStrSec : TAsmSection;
  146. procedure section_reset(p:tnamedindexitem;arg:pointer);
  147. procedure section_fixuprelocs(p:tnamedindexitem;arg:pointer);
  148. protected
  149. property StabsRecSize:longint read FStabsRecSize write FStabsRecSize;
  150. property StabsSec:TAsmSection read FStabsSec write FStabsSec;
  151. property StabStrSec:TAsmSection read FStabStrSec write FStabStrSec;
  152. property CAsmSection:TAsmSectionClass read FCAsmSection write FCAsmSection;
  153. public
  154. constructor create(const n:string);virtual;
  155. destructor destroy;override;
  156. function sectionname(atype:tasmsectiontype;const aname:string):string;virtual;
  157. function createsection(atype:tasmsectiontype;const aname:string;aalign:longint;aoptions:TAsmSectionOptions):tasmsection;virtual;
  158. procedure setsection(asec:tasmsection);
  159. procedure alloc(len:aint);
  160. procedure allocalign(len:longint);
  161. procedure allocstabs(p:pchar);
  162. procedure allocsymbol(currpass:byte;p:tasmsymbol;len:aint);
  163. procedure writebytes(var data;len:aint);
  164. procedure writereloc(data,len:aint;p:tasmsymbol;relative:TAsmRelocationType);virtual;abstract;
  165. procedure writesymbol(p:tasmsymbol);virtual;abstract;
  166. procedure writestabs(offset:aint;p:pchar;nidx,nother,line:longint;reloc:boolean);virtual;abstract;
  167. procedure writesymstabs(offset:aint;p:pchar;ps:tasmsymbol;nidx,nother,line:longint;reloc:boolean);virtual;abstract;
  168. procedure beforealloc;virtual;
  169. procedure beforewrite;virtual;
  170. procedure afteralloc;virtual;
  171. procedure afterwrite;virtual;
  172. procedure resetsections;
  173. procedure fixuprelocs;
  174. property Name:string{$ifndef VER1_9_4}[80]{$endif} read FName;
  175. property CurrSec:TAsmSection read FCurrSec;
  176. property Symbols:TindexArray read FSymbols;
  177. property Sects:TDictionary read FSects;
  178. end;
  179. TAsmObjectDataClass = class of TAsmObjectData;
  180. tasmsymbolidxarr = array[0..($7fffffff div sizeof(pointer))-1] of tasmsymbol;
  181. pasmsymbolidxarr = ^tasmsymbolidxarr;
  182. TAsmLibraryData = class(TLinkedListItem)
  183. private
  184. nextaltnr : longint;
  185. nextlabelnr : longint;
  186. public
  187. name,
  188. realname : string[80];
  189. symbolsearch : tdictionary; { contains ALL assembler symbols }
  190. usedasmsymbollist : tsinglelist;
  191. { ppu }
  192. asmsymbolppuidx : longint;
  193. asmsymbolidx : pasmsymbolidxarr; { used for translating ppu index->asmsymbol }
  194. constructor create(const n:string);
  195. destructor destroy;override;
  196. procedure Freeasmsymbolidx;
  197. procedure DerefAsmsymbol(var s:tasmsymbol);
  198. { asmsymbol }
  199. function newasmsymbol(const s : string;_bind:TAsmSymBind;_typ:TAsmsymtype) : tasmsymbol;
  200. function getasmsymbol(const s : string) : tasmsymbol;
  201. function renameasmsymbol(const sold, snew : string):tasmsymbol;
  202. function newasmlabel(nr:longint;is_addr,is_data:boolean) : tasmlabel;
  203. {# create a new assembler label }
  204. procedure getlabel(var l : tasmlabel);
  205. { make l as a new label and flag is_addr }
  206. procedure getaddrlabel(var l : tasmlabel);
  207. { make l as a new label and flag is_data }
  208. procedure getdatalabel(var l : tasmlabel);
  209. {# return a label number }
  210. procedure getlabelnr(var l : longint);
  211. procedure CreateUsedAsmSymbolList;
  212. procedure DestroyUsedAsmSymbolList;
  213. procedure UsedAsmSymbolListInsert(p:tasmsymbol);
  214. { generate an alternative (duplicate) symbol }
  215. procedure GenerateAltSymbol(p:tasmsymbol);
  216. { reset alternative symbol information }
  217. procedure UsedAsmSymbolListResetAltSym;
  218. procedure UsedAsmSymbolListReset;
  219. procedure UsedAsmSymbolListCheckUndefined;
  220. end;
  221. var
  222. objectlibrary : tasmlibrarydata;
  223. implementation
  224. uses
  225. strings,
  226. verbose;
  227. const
  228. symbolsgrow = 100;
  229. {*****************************************************************************
  230. TAsmSymbol
  231. *****************************************************************************}
  232. constructor tasmsymbol.create(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  233. begin;
  234. inherited createname(s);
  235. reset;
  236. defbind:=_bind;
  237. typ:=_typ;
  238. inusedlist:=false;
  239. pass:=255;
  240. ppuidx:=-1;
  241. { mainly used to remove unused labels from the codesegment }
  242. refs:=0;
  243. end;
  244. procedure tasmsymbol.reset;
  245. begin
  246. { reset section info }
  247. section:=nil;
  248. address:=0;
  249. size:=0;
  250. indexnr:=-1;
  251. pass:=255;
  252. currbind:=AB_EXTERNAL;
  253. altsymbol:=nil;
  254. { taiowner:=nil;}
  255. end;
  256. function tasmsymbol.is_used:boolean;
  257. begin
  258. is_used:=(refs>0);
  259. end;
  260. procedure tasmsymbol.increfs;
  261. begin
  262. inc(refs);
  263. end;
  264. procedure tasmsymbol.decrefs;
  265. begin
  266. dec(refs);
  267. if refs<0 then
  268. internalerror(200211121);
  269. end;
  270. function tasmsymbol.getrefs: longint;
  271. begin
  272. getrefs := refs;
  273. end;
  274. procedure tasmsymbol.setaddress(_pass:byte;sec:TAsmSection;offset,len:aint);
  275. begin
  276. if (_pass=pass) then
  277. begin
  278. Message1(asmw_e_duplicate_label,name);
  279. exit;
  280. end;
  281. pass:=_pass;
  282. section:=sec;
  283. address:=offset;
  284. size:=len;
  285. { when the bind was reset to External, set it back to the default
  286. bind it got when defined }
  287. if (currbind=AB_EXTERNAL) and (defbind<>AB_NONE) then
  288. currbind:=defbind;
  289. end;
  290. {*****************************************************************************
  291. TAsmLabel
  292. *****************************************************************************}
  293. constructor tasmlabel.create(nr:longint);
  294. begin;
  295. labelnr:=nr;
  296. inherited create(target_asm.labelprefix+tostr(labelnr),AB_LOCAL,AT_FUNCTION);
  297. is_set:=false;
  298. is_addr := false;
  299. end;
  300. constructor tasmlabel.createdata(const modulename:string;nr:longint);
  301. begin;
  302. labelnr:=nr;
  303. inherited create('_$'+modulename+'$_L'+tostr(labelnr),AB_GLOBAL,AT_DATA);
  304. is_set:=false;
  305. is_addr := false;
  306. { write it always }
  307. increfs;
  308. end;
  309. constructor tasmlabel.createaddr(nr:longint);
  310. begin;
  311. self.create(nr);
  312. is_addr := true;
  313. end;
  314. function tasmlabel.getname:string;
  315. begin
  316. getname:=inherited getname;
  317. increfs;
  318. end;
  319. {****************************************************************************
  320. TAsmRelocation
  321. ****************************************************************************}
  322. constructor TAsmRelocation.CreateSymbol(Aaddress:aint;s:Tasmsymbol;Atyp:TAsmRelocationType);
  323. begin
  324. Address:=Aaddress;
  325. Symbol:=s;
  326. OrgSize:=0;
  327. Section:=nil;
  328. Typ:=Atyp;
  329. end;
  330. constructor TAsmRelocation.CreateSymbolSize(Aaddress:aint;s:Tasmsymbol;Aorgsize:aint;Atyp:TAsmRelocationType);
  331. begin
  332. Address:=Aaddress;
  333. Symbol:=s;
  334. OrgSize:=Aorgsize;
  335. Section:=nil;
  336. Typ:=Atyp;
  337. end;
  338. constructor TAsmRelocation.CreateSection(Aaddress:aint;sec:TAsmSection;Atyp:TAsmRelocationType);
  339. begin
  340. Address:=Aaddress;
  341. Symbol:=nil;
  342. OrgSize:=0;
  343. Section:=sec;
  344. Typ:=Atyp;
  345. end;
  346. {****************************************************************************
  347. TAsmSection
  348. ****************************************************************************}
  349. constructor TAsmSection.create(const Aname:string;Atype:TAsmSectionType;Aalign:longint;Aoptions:TAsmSectionOptions);
  350. begin
  351. inherited createname(Aname);
  352. sectype:=Atype;
  353. name:=Aname;
  354. secoptions:=Aoptions;
  355. secsymidx:=0;
  356. addralign:=Aalign;
  357. { data }
  358. datasize:=0;
  359. datapos:=0;
  360. if (aso_alloconly in aoptions) then
  361. data:=nil
  362. else
  363. Data:=TDynamicArray.Create(8192);
  364. { memory }
  365. mempos:=0;
  366. memsize:=0;
  367. { relocation }
  368. relocations:=TLinkedList.Create;
  369. end;
  370. destructor TAsmSection.destroy;
  371. begin
  372. if assigned(Data) then
  373. Data.Free;
  374. relocations.free;
  375. end;
  376. function TAsmSection.write(const d;l:aint):aint;
  377. begin
  378. write:=datasize;
  379. if assigned(Data) then
  380. Data.write(d,l);
  381. inc(datasize,l);
  382. end;
  383. function TAsmSection.writestr(const s:string):aint;
  384. begin
  385. writestr:=datasize;
  386. if assigned(Data) then
  387. Data.write(s[1],length(s));
  388. inc(datasize,length(s));
  389. end;
  390. procedure TAsmSection.writealign(l:longint);
  391. var
  392. i : longint;
  393. empty : array[0..63] of char;
  394. begin
  395. { no alignment needed for 0 or 1 }
  396. if l<=1 then
  397. exit;
  398. i:=datasize mod l;
  399. if i>0 then
  400. begin
  401. if assigned(data) then
  402. begin
  403. fillchar(empty,sizeof(empty),0);
  404. Data.write(empty,l-i);
  405. end;
  406. inc(datasize,l-i);
  407. end;
  408. end;
  409. function TAsmSection.aligneddatasize:aint;
  410. begin
  411. aligneddatasize:=align(datasize,addralign);
  412. end;
  413. procedure TAsmSection.setdatapos(var dpos:aint);
  414. var
  415. alignedpos : aint;
  416. begin
  417. { get aligned datapos }
  418. alignedpos:=align(dpos,addralign);
  419. dataalignbytes:=alignedpos-dpos;
  420. datapos:=alignedpos;
  421. { update datapos }
  422. dpos:=datapos+aligneddatasize;
  423. end;
  424. procedure TAsmSection.alignsection;
  425. begin
  426. writealign(addralign);
  427. end;
  428. procedure TAsmSection.alloc(l:aint);
  429. begin
  430. inc(datasize,l);
  431. end;
  432. procedure TAsmSection.addsymreloc(ofs:aint;p:tasmsymbol;relative:TAsmRelocationType);
  433. var
  434. r : TAsmRelocation;
  435. begin
  436. r:=TAsmRelocation.Create;
  437. r.address:=ofs;
  438. r.orgsize:=0;
  439. r.symbol:=p;
  440. r.section:=nil;
  441. r.typ:=relative;
  442. relocations.concat(r);
  443. end;
  444. procedure TAsmSection.addsectionreloc(ofs:aint;sec:TAsmSection;relative:TAsmRelocationType);
  445. var
  446. r : TAsmRelocation;
  447. begin
  448. r:=TAsmRelocation.Create;
  449. r.address:=ofs;
  450. r.symbol:=nil;
  451. r.orgsize:=0;
  452. r.section:=sec;
  453. r.typ:=relative;
  454. relocations.concat(r);
  455. end;
  456. procedure TAsmSection.fixuprelocs;
  457. begin
  458. end;
  459. {****************************************************************************
  460. TAsmObjectData
  461. ****************************************************************************}
  462. constructor TAsmObjectData.create(const n:string);
  463. begin
  464. inherited create;
  465. FName:=n;
  466. { sections }
  467. FSects:=tdictionary.create;
  468. FStabsRecSize:=1;
  469. FStabsSec:=nil;
  470. FStabStrSec:=nil;
  471. { symbols }
  472. FSymbols:=tindexarray.create(symbolsgrow);
  473. FSymbols.noclear:=true;
  474. { section class type for creating of new sections }
  475. FCAsmSection:=TAsmSection;
  476. end;
  477. destructor TAsmObjectData.destroy;
  478. begin
  479. FSects.free;
  480. FSymbols.free;
  481. end;
  482. function TAsmObjectData.sectionname(atype:tasmsectiontype;const aname:string):string;
  483. const
  484. secnames : array[tasmsectiontype] of string[12] = ('',
  485. 'code','data','rodata','bss',
  486. 'common',
  487. 'note',
  488. 'stab','stabstr',
  489. 'idata2','idata4','idata5','idata6','idata7','edata',
  490. 'eh_frame',
  491. 'debug_frame'
  492. );
  493. begin
  494. if aname<>'' then
  495. result:=secnames[atype]+'.'+aname
  496. else
  497. result:=secnames[atype];
  498. end;
  499. function TAsmObjectData.createsection(atype:tasmsectiontype;const aname:string;aalign:longint;aoptions:TAsmSectionOptions):TAsmSection;
  500. var
  501. secname : string;
  502. begin
  503. secname:=sectionname(atype,aname);
  504. result:=TasmSection(FSects.search(secname));
  505. if not assigned(result) then
  506. begin
  507. {$warning TODO make alloconly configurable}
  508. if atype=sec_bss then
  509. include(aoptions,aso_alloconly);
  510. result:=CAsmSection.create(secname,atype,aalign,aoptions);
  511. FSects.Insert(result);
  512. result.owner:=self;
  513. end;
  514. FCurrSec:=result;
  515. end;
  516. procedure TAsmObjectData.setsection(asec:tasmsection);
  517. begin
  518. if asec.owner<>self then
  519. internalerror(200403041);
  520. FCurrSec:=asec;
  521. end;
  522. procedure TAsmObjectData.writebytes(var data;len:aint);
  523. begin
  524. if not assigned(currsec) then
  525. internalerror(200402251);
  526. currsec.write(data,len);
  527. end;
  528. procedure TAsmObjectData.alloc(len:aint);
  529. begin
  530. if not assigned(currsec) then
  531. internalerror(200402252);
  532. currsec.alloc(len);
  533. end;
  534. procedure TAsmObjectData.allocalign(len:longint);
  535. var
  536. modulo : aint;
  537. begin
  538. if not assigned(currsec) then
  539. internalerror(200402253);
  540. modulo:=currsec.datasize mod len;
  541. if modulo > 0 then
  542. currsec.alloc(len-modulo);
  543. end;
  544. procedure TAsmObjectData.allocsymbol(currpass:byte;p:tasmsymbol;len:aint);
  545. begin
  546. p.setaddress(currpass,currsec,currsec.datasize,len);
  547. end;
  548. procedure TAsmObjectData.allocstabs(p:pchar);
  549. begin
  550. if not(assigned(FStabsSec) and assigned(FStabStrSec)) then
  551. internalerror(200402254);
  552. FStabsSec.alloc(FStabsRecSize);
  553. if assigned(p) and (p[0]<>#0) then
  554. FStabStrSec.alloc(strlen(p)+1);
  555. end;
  556. procedure TAsmObjectData.section_reset(p:tnamedindexitem;arg:pointer);
  557. begin
  558. with tasmsection(p) do
  559. begin
  560. datasize:=0;
  561. datapos:=0;
  562. end;
  563. end;
  564. procedure TAsmObjectData.section_fixuprelocs(p:tnamedindexitem;arg:pointer);
  565. begin
  566. tasmsection(p).fixuprelocs;
  567. end;
  568. procedure TAsmObjectData.beforealloc;
  569. begin
  570. end;
  571. procedure TAsmObjectData.beforewrite;
  572. begin
  573. end;
  574. procedure TAsmObjectData.afteralloc;
  575. begin
  576. end;
  577. procedure TAsmObjectData.afterwrite;
  578. begin
  579. end;
  580. procedure TAsmObjectData.resetsections;
  581. begin
  582. FSects.foreach(@section_reset,nil);
  583. end;
  584. procedure TAsmObjectData.fixuprelocs;
  585. begin
  586. FSects.foreach(@section_fixuprelocs,nil);
  587. end;
  588. {****************************************************************************
  589. TAsmLibraryData
  590. ****************************************************************************}
  591. constructor TAsmLibraryData.create(const n:string);
  592. begin
  593. inherited create;
  594. realname:=n;
  595. name:=upper(n);
  596. { symbols }
  597. symbolsearch:=tdictionary.create;
  598. symbolsearch.usehash;
  599. { labels }
  600. nextaltnr:=1;
  601. nextlabelnr:=1;
  602. { ppu }
  603. asmsymbolppuidx:=0;
  604. asmsymbolidx:=nil;
  605. end;
  606. destructor TAsmLibraryData.destroy;
  607. begin
  608. symbolsearch.free;
  609. Freeasmsymbolidx;
  610. end;
  611. procedure TAsmLibraryData.Freeasmsymbolidx;
  612. begin
  613. if assigned(asmsymbolidx) then
  614. begin
  615. Freemem(asmsymbolidx);
  616. asmsymbolidx:=nil;
  617. end;
  618. end;
  619. procedure TAsmLibraryData.DerefAsmsymbol(var s:tasmsymbol);
  620. begin
  621. if assigned(s) then
  622. begin
  623. if not assigned(asmsymbolidx) then
  624. internalerror(200208072);
  625. if (ptrint(pointer(s))<1) or (ptrint(pointer(s))>asmsymbolppuidx) then
  626. internalerror(200208073);
  627. s:=asmsymbolidx^[ptrint(pointer(s))-1];
  628. end;
  629. end;
  630. function TAsmLibraryData.newasmsymbol(const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : tasmsymbol;
  631. var
  632. hp : tasmsymbol;
  633. begin
  634. hp:=tasmsymbol(symbolsearch.search(s));
  635. if assigned(hp) then
  636. begin
  637. {$IFDEF EXTDEBUG}
  638. if (_typ <> AT_NONE) and
  639. (hp.typ <> _typ) and
  640. not(cs_compilesystem in aktmoduleswitches) then
  641. begin
  642. //Writeln('Error symbol '+hp.name+' type is ',Ord(_typ),', should be ',Ord(hp.typ));
  643. InternalError(2004031501);
  644. end;
  645. {$ENDIF}
  646. if (_bind<>AB_EXTERNAL) then
  647. hp.defbind:=_bind
  648. end
  649. else
  650. begin
  651. { Not found, insert it. }
  652. hp:=tasmsymbol.create(s,_bind,_typ);
  653. symbolsearch.insert(hp);
  654. end;
  655. newasmsymbol:=hp;
  656. end;
  657. function TAsmLibraryData.getasmsymbol(const s : string) : tasmsymbol;
  658. begin
  659. getasmsymbol:=tasmsymbol(symbolsearch.search(s));
  660. end;
  661. function TAsmLibraryData.renameasmsymbol(const sold, snew : string):tasmsymbol;
  662. begin
  663. renameasmsymbol:=tasmsymbol(symbolsearch.rename(sold,snew));
  664. end;
  665. procedure TAsmLibraryData.CreateUsedAsmSymbolList;
  666. begin
  667. if assigned(usedasmsymbollist) then
  668. internalerror(78455782);
  669. usedasmsymbollist:=TSingleList.create;
  670. end;
  671. procedure TAsmLibraryData.DestroyUsedAsmSymbolList;
  672. begin
  673. usedasmsymbollist.destroy;
  674. usedasmsymbollist:=nil;
  675. end;
  676. procedure TAsmLibraryData.UsedAsmSymbolListInsert(p:tasmsymbol);
  677. begin
  678. if not p.inusedlist then
  679. usedasmsymbollist.insert(p);
  680. p.inusedlist:=true;
  681. end;
  682. procedure TAsmLibraryData.GenerateAltSymbol(p:tasmsymbol);
  683. begin
  684. if not assigned(p.altsymbol) then
  685. begin
  686. p.altsymbol:=tasmsymbol.create(p.name+'_'+tostr(nextaltnr),p.defbind,p.typ);
  687. symbolsearch.insert(p.altsymbol);
  688. { add also the original sym to the usedasmsymbollist,
  689. that list is used to reset the altsymbol }
  690. if not p.inusedlist then
  691. usedasmsymbollist.insert(p);
  692. p.inusedlist:=true;
  693. end;
  694. end;
  695. procedure TAsmLibraryData.UsedAsmSymbolListReset;
  696. var
  697. hp : tasmsymbol;
  698. begin
  699. hp:=tasmsymbol(usedasmsymbollist.first);
  700. while assigned(hp) do
  701. begin
  702. with hp do
  703. begin
  704. reset;
  705. inusedlist:=false;
  706. end;
  707. hp:=tasmsymbol(hp.listnext);
  708. end;
  709. end;
  710. procedure TAsmLibraryData.UsedAsmSymbolListResetAltSym;
  711. var
  712. hp : tasmsymbol;
  713. begin
  714. hp:=tasmsymbol(usedasmsymbollist.first);
  715. inc(nextaltnr);
  716. while assigned(hp) do
  717. begin
  718. with hp do
  719. begin
  720. altsymbol:=nil;
  721. inusedlist:=false;
  722. end;
  723. hp:=tasmsymbol(hp.listnext);
  724. end;
  725. end;
  726. procedure TAsmLibraryData.UsedAsmSymbolListCheckUndefined;
  727. var
  728. hp : tasmsymbol;
  729. begin
  730. hp:=tasmsymbol(usedasmsymbollist.first);
  731. while assigned(hp) do
  732. begin
  733. with hp do
  734. begin
  735. if is_used and
  736. (section=nil) and
  737. not(currbind in [AB_EXTERNAL,AB_COMMON]) then
  738. Message1(asmw_e_undefined_label,name);
  739. end;
  740. hp:=tasmsymbol(hp.listnext);
  741. end;
  742. end;
  743. function TAsmLibraryData.newasmlabel(nr:longint;is_addr,is_data:boolean) : tasmlabel;
  744. var
  745. hp : tasmlabel;
  746. begin
  747. if is_addr then
  748. hp:=tasmlabel.createaddr(nr)
  749. else if is_data then
  750. hp:=tasmlabel.createdata(name,nr)
  751. else
  752. hp:=tasmlabel.create(nr);
  753. symbolsearch.insert(hp);
  754. newasmlabel:=hp;
  755. end;
  756. procedure TAsmLibraryData.getlabel(var l : tasmlabel);
  757. begin
  758. l:=tasmlabel.create(nextlabelnr);
  759. inc(nextlabelnr);
  760. symbolsearch.insert(l);
  761. end;
  762. procedure TAsmLibraryData.getdatalabel(var l : tasmlabel);
  763. begin
  764. l:=tasmlabel.createdata(name,nextlabelnr);
  765. inc(nextlabelnr);
  766. symbolsearch.insert(l);
  767. end;
  768. procedure TAsmLibraryData.getaddrlabel(var l : tasmlabel);
  769. begin
  770. l:=tasmlabel.createaddr(nextlabelnr);
  771. inc(nextlabelnr);
  772. symbolsearch.insert(l);
  773. end;
  774. procedure TAsmLibraryData.getlabelnr(var l : longint);
  775. begin
  776. l:=nextlabelnr;
  777. inc(nextlabelnr);
  778. end;
  779. end.
  780. {
  781. $Log$
  782. Revision 1.25 2004-12-03 15:57:11 peter
  783. * fix for 1.9.4 that IE'd when rebuilding fpc
  784. Revision 1.24 2004/11/01 23:30:11 peter
  785. * support > 32bit accesses for x86_64
  786. * rewrote array size checking to support 64bit
  787. Revision 1.23 2004/10/31 21:45:02 peter
  788. * generic tlocation
  789. * move tlocation to cgutils
  790. Revision 1.22 2004/10/15 09:14:16 mazen
  791. - remove $IFDEF DELPHI and related code
  792. - remove $IFDEF FPCPROCVAR and related code
  793. Revision 1.21 2004/07/22 10:09:10 jonas
  794. * fixed relabeling properly now :)
  795. Revision 1.20 2004/07/22 10:07:09 jonas
  796. * fixed relabeling (nextaltnr was never increased)
  797. * fixed inlining of case statements at the node level
  798. Revision 1.19 2004/06/20 08:55:28 florian
  799. * logs truncated
  800. Revision 1.18 2004/06/16 20:07:06 florian
  801. * dwarf branch merged
  802. Revision 1.17.2.4 2004/05/11 21:04:40 peter
  803. * ignore EXTDEBUG check for different asmsymbol type for system unit
  804. Revision 1.17.2.3 2004/04/26 21:05:09 peter
  805. * size of classes is now stored as aint
  806. Revision 1.17.2.2 2004/04/12 19:34:45 peter
  807. * basic framework for dwarf CFI
  808. Revision 1.17.2.1 2004/04/08 18:33:22 peter
  809. * rewrite of TAsmSection
  810. }