aasmbase.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  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. { asm symbol functions }
  30. type
  31. TAsmsymbind=(AB_NONE,AB_EXTERNAL,AB_COMMON,AB_LOCAL,AB_GLOBAL);
  32. TAsmsymtype=(AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION);
  33. TAsmRelocationType = (RELOC_ABSOLUTE,RELOC_RELATIVE,RELOC_RVA);
  34. TAsmSectionSizes = array[TSection] of longint;
  35. TAsmSymbol = class(TNamedIndexItem)
  36. private
  37. { this need to be incremented with every symbol loading into the
  38. paasmoutput, thus in loadsym/loadref/const_symbol (PFV) }
  39. refs : longint;
  40. public
  41. defbind,
  42. currbind : TAsmsymbind;
  43. typ : TAsmsymtype;
  44. { the next fields are filled in the binary writer }
  45. section : TSection;
  46. address,
  47. size : longint;
  48. { Alternate symbol which can be used for 'renaming' needed for
  49. inlining }
  50. altsymbol : tasmsymbol;
  51. { pointer to objectdata that is the owner of this symbol }
  52. objectdata : pointer;
  53. { pointer to the tai that is the owner of this symbol }
  54. { taiowner : pointer;}
  55. { Is the symbol in the used list }
  56. inusedlist : boolean;
  57. { assembler pass label is set, used for detecting multiple labels }
  58. pass : byte;
  59. ppuidx : longint;
  60. constructor create(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  61. procedure reset;
  62. function is_used:boolean;
  63. procedure increfs;
  64. procedure decrefs;
  65. procedure setaddress(_pass:byte;sec:TSection;offset,len:longint);
  66. end;
  67. TAsmLabel = class(TAsmSymbol)
  68. { this is set by the tai_label.Init }
  69. is_set,
  70. { is the label only there for getting an address (e.g. for i/o }
  71. { checks -> true) or is it a jump target (false) }
  72. is_addr : boolean;
  73. labelnr : longint;
  74. constructor create(nr:longint);
  75. constructor createdata(nr:longint);
  76. constructor createaddr(nr:longint);
  77. function getname:string;override;
  78. end;
  79. TAsmRelocation = class(TLinkedListItem)
  80. address,
  81. orgsize : longint; { original size of the symbol to relocate, required for COFF }
  82. symbol : tasmsymbol;
  83. section : TSection; { only used if symbol=nil }
  84. typ : TAsmRelocationType;
  85. constructor CreateSymbol(Aaddress:longint;s:Tasmsymbol;Atyp:TAsmRelocationType);
  86. constructor CreateSymbolSize(Aaddress:longint;s:Tasmsymbol;Aorgsize:longint;Atyp:TAsmRelocationType);
  87. constructor CreateSection(Aaddress:longint;sec:TSection;Atyp:TAsmRelocationType);
  88. end;
  89. TAsmSection = class(TLinkedListItem)
  90. name : string[32];
  91. secsymidx : longint; { index for the section in symtab }
  92. addralign : longint; { alignment of the section }
  93. flags : cardinal; { section flags }
  94. { size of the data and in the file }
  95. dataalignbytes : longint;
  96. data : TDynamicArray;
  97. datasize : longint;
  98. datapos : longint;
  99. { size and position in memory, set by seTSectionsize }
  100. memsize,
  101. mempos : longint;
  102. { relocation }
  103. relocations : TLinkedList;
  104. constructor create(const Aname:string;Aalign:longint;alloconly:boolean);
  105. destructor destroy;override;
  106. function write(var d;l:longint):longint;
  107. function writestr(const s:string):longint;
  108. procedure writealign(l:longint);
  109. function aligneddatasize:longint;
  110. procedure alignsection;
  111. procedure alloc(l:longint);
  112. procedure addsymreloc(ofs:longint;p:tasmsymbol;relative:TAsmRelocationType);
  113. procedure addsectionreloc(ofs:longint;sec:TSection;relative:TAsmRelocationType);
  114. end;
  115. TAsmObjectAlloc = class
  116. currsec : TSection;
  117. secsize : TAsmSectionSizes;
  118. constructor create;
  119. destructor destroy;override;
  120. procedure seTSection(sec:TSection);
  121. function sectionsize:longint;
  122. procedure sectionalloc(l:longint);
  123. procedure sectionalign(l:longint);
  124. procedure staballoc(p:pchar);
  125. procedure resetSections;
  126. end;
  127. TAsmObjectData = class(TLinkedListItem)
  128. public
  129. name : string[80];
  130. currsec : TSection;
  131. sects : array[TSection] of TAsmSection;
  132. symbols : tindexarray; { contains symbols that will be defined in object file }
  133. constructor create(const n:string);
  134. destructor destroy;override;
  135. procedure createsection(sec:TSection);virtual;
  136. procedure defaulTSection(sec:TSection);
  137. function sectionsize(s:TSection):longint;
  138. function currsectionsize:longint;
  139. procedure setsectionsizes(var s:TAsmSectionSizes);virtual;
  140. procedure alloc(len:longint);
  141. procedure allocalign(len:longint);
  142. procedure writebytes(var data;len:longint);
  143. procedure writereloc(data,len:longint;p:tasmsymbol;relative:TAsmRelocationType);virtual;abstract;
  144. procedure writesymbol(p:tasmsymbol);virtual;abstract;
  145. procedure writestabs(section:TSection;offset:longint;p:pchar;nidx,nother,line:longint;reloc:boolean);virtual;abstract;
  146. procedure writesymstabs(section:TSection;offset:longint;p:pchar;ps:tasmsymbol;nidx,nother,line:longint;reloc:boolean);virtual;abstract;
  147. procedure fixuprelocs;virtual;
  148. end;
  149. {$ifndef delphi}
  150. tasmsymbolidxarr = array[0..($7fffffff div sizeof(pointer))] of tasmsymbol;
  151. {$else}
  152. tasmsymbolidxarr = array[0..high(word)] of tasmsymbol;
  153. {$endif}
  154. pasmsymbolidxarr = ^tasmsymbolidxarr;
  155. TAsmLibraryData = class(TLinkedListItem)
  156. private
  157. nextaltnr : longint;
  158. nextlabelnr : longint;
  159. public
  160. name : string[80];
  161. symbolsearch : tdictionary; { contains ALL assembler symbols }
  162. usedasmsymbollist : tsinglelist;
  163. { ppu }
  164. asmsymbolppuidx : longint;
  165. asmsymbolidx : pasmsymbolidxarr; { used for translating ppu index->asmsymbol }
  166. constructor create(const n:string);
  167. destructor destroy;override;
  168. procedure Freeasmsymbolidx;
  169. procedure DerefAsmsymbol(var s:tasmsymbol);
  170. { asmsymbol }
  171. function newasmsymbol(const s : string) : tasmsymbol;
  172. function newasmsymboltype(const s : string;_bind:TAsmSymBind;_typ:TAsmsymtype) : tasmsymbol;
  173. function getasmsymbol(const s : string) : tasmsymbol;
  174. function renameasmsymbol(const sold, snew : string):tasmsymbol;
  175. function newasmlabel(nr:longint;is_addr,is_data:boolean) : tasmlabel;
  176. {# create a new assembler label }
  177. procedure getlabel(var l : tasmlabel);
  178. { make l as a new label and flag is_addr }
  179. procedure getaddrlabel(var l : tasmlabel);
  180. { make l as a new label and flag is_data }
  181. procedure getdatalabel(var l : tasmlabel);
  182. {# return a label number }
  183. procedure getlabelnr(var l : longint);
  184. procedure CreateUsedAsmSymbolList;
  185. procedure DestroyUsedAsmSymbolList;
  186. procedure UsedAsmSymbolListInsert(p:tasmsymbol);
  187. { generate an alternative (duplicate) symbol }
  188. procedure GenerateAltSymbol(p:tasmsymbol);
  189. { reset alternative symbol information }
  190. procedure UsedAsmSymbolListResetAltSym;
  191. procedure UsedAsmSymbolListReset;
  192. procedure UsedAsmSymbolListCheckUndefined;
  193. end;
  194. var
  195. objectlibrary : tasmlibrarydata;
  196. implementation
  197. uses
  198. {$ifdef delphi}
  199. sysutils,
  200. {$else}
  201. strings,
  202. {$endif}
  203. fmodule,verbose;
  204. const
  205. symbolsgrow = 100;
  206. {*****************************************************************************
  207. TAsmSymbol
  208. *****************************************************************************}
  209. constructor tasmsymbol.create(const s:string;_bind:TAsmsymbind;_typ:Tasmsymtype);
  210. begin;
  211. inherited createname(s);
  212. reset;
  213. defbind:=_bind;
  214. typ:=_typ;
  215. inusedlist:=false;
  216. pass:=255;
  217. ppuidx:=-1;
  218. { mainly used to remove unused labels from the codesegment }
  219. refs:=0;
  220. end;
  221. procedure tasmsymbol.reset;
  222. begin
  223. { WriteLn(ClassName,' InstanceSize :',InstanceSize);}
  224. { reset section info }
  225. section:=sec_none;
  226. address:=0;
  227. size:=0;
  228. indexnr:=-1;
  229. pass:=255;
  230. currbind:=AB_EXTERNAL;
  231. altsymbol:=nil;
  232. { taiowner:=nil;}
  233. end;
  234. function tasmsymbol.is_used:boolean;
  235. begin
  236. is_used:=(refs>0);
  237. end;
  238. procedure tasmsymbol.increfs;
  239. begin
  240. inc(refs);
  241. end;
  242. procedure tasmsymbol.decrefs;
  243. begin
  244. dec(refs);
  245. if refs<0 then
  246. internalerror(200211121);
  247. end;
  248. procedure tasmsymbol.setaddress(_pass:byte;sec:TSection;offset,len:longint);
  249. begin
  250. if (_pass=pass) then
  251. begin
  252. Message1(asmw_e_duplicate_label,name);
  253. exit;
  254. end;
  255. pass:=_pass;
  256. section:=sec;
  257. address:=offset;
  258. size:=len;
  259. { when the bind was reset to External, set it back to the default
  260. bind it got when defined }
  261. if (currbind=AB_EXTERNAL) and (defbind<>AB_NONE) then
  262. currbind:=defbind;
  263. end;
  264. {*****************************************************************************
  265. TAsmLabel
  266. *****************************************************************************}
  267. constructor tasmlabel.create(nr:longint);
  268. begin;
  269. labelnr:=nr;
  270. inherited create(target_asm.labelprefix+tostr(labelnr),AB_LOCAL,AT_FUNCTION);
  271. is_set:=false;
  272. is_addr := false;
  273. end;
  274. constructor tasmlabel.createdata(nr:longint);
  275. begin;
  276. labelnr:=nr;
  277. if (cs_create_smart in aktmoduleswitches) or
  278. target_asm.labelprefix_only_inside_procedure then
  279. inherited create('_$'+current_module.modulename^+'$_L'+tostr(labelnr),AB_GLOBAL,AT_DATA)
  280. else
  281. inherited create(target_asm.labelprefix+tostr(labelnr),AB_LOCAL,AT_DATA);
  282. is_set:=false;
  283. is_addr := false;
  284. { write it always }
  285. increfs;
  286. end;
  287. constructor tasmlabel.createaddr(nr:longint);
  288. begin;
  289. create(nr);
  290. is_addr := true;
  291. end;
  292. function tasmlabel.getname:string;
  293. begin
  294. getname:=inherited getname;
  295. increfs;
  296. end;
  297. {****************************************************************************
  298. TAsmObjectAlloc
  299. ****************************************************************************}
  300. constructor TAsmObjectAlloc.create;
  301. begin
  302. end;
  303. destructor TAsmObjectAlloc.destroy;
  304. begin
  305. end;
  306. procedure TAsmObjectAlloc.seTSection(sec:TSection);
  307. begin
  308. currsec:=sec;
  309. end;
  310. procedure TAsmObjectAlloc.reseTSections;
  311. begin
  312. FillChar(secsize,sizeof(secsize),0);
  313. end;
  314. procedure TAsmObjectAlloc.sectionalloc(l:longint);
  315. begin
  316. inc(secsize[currsec],l);
  317. end;
  318. procedure TAsmObjectAlloc.sectionalign(l:longint);
  319. begin
  320. if (secsize[currsec] mod l)<>0 then
  321. inc(secsize[currsec],l-(secsize[currsec] mod l));
  322. end;
  323. procedure TAsmObjectAlloc.staballoc(p:pchar);
  324. begin
  325. inc(secsize[sec_stab]);
  326. if assigned(p) and (p[0]<>#0) then
  327. inc(secsize[sec_stabstr],strlen(p)+1);
  328. end;
  329. function TAsmObjectAlloc.sectionsize:longint;
  330. begin
  331. sectionsize:=secsize[currsec];
  332. end;
  333. {****************************************************************************
  334. TAsmRelocation
  335. ****************************************************************************}
  336. constructor TAsmRelocation.CreateSymbol(Aaddress:longint;s:Tasmsymbol;Atyp:TAsmRelocationType);
  337. begin
  338. Address:=Aaddress;
  339. Symbol:=s;
  340. OrgSize:=0;
  341. Section:=Sec_none;
  342. Typ:=Atyp;
  343. end;
  344. constructor TAsmRelocation.CreateSymbolSize(Aaddress:longint;s:Tasmsymbol;Aorgsize:longint;Atyp:TAsmRelocationType);
  345. begin
  346. Address:=Aaddress;
  347. Symbol:=s;
  348. OrgSize:=Aorgsize;
  349. Section:=Sec_none;
  350. Typ:=Atyp;
  351. end;
  352. constructor TAsmRelocation.CreateSection(Aaddress:longint;sec:TSection;Atyp:TAsmRelocationType);
  353. begin
  354. Address:=Aaddress;
  355. Symbol:=nil;
  356. OrgSize:=0;
  357. Section:=sec;
  358. Typ:=Atyp;
  359. end;
  360. {****************************************************************************
  361. TAsmSection
  362. ****************************************************************************}
  363. constructor TAsmSection.create(const Aname:string;Aalign:longint;alloconly:boolean);
  364. begin
  365. inherited create;
  366. name:=Aname;
  367. secsymidx:=0;
  368. addralign:=Aalign;
  369. { data }
  370. datasize:=0;
  371. datapos:=0;
  372. if alloconly then
  373. data:=nil
  374. else
  375. Data:=TDynamicArray.Create(8192);
  376. { position }
  377. mempos:=0;
  378. memsize:=0;
  379. { relocation }
  380. relocations:=TLinkedList.Create;
  381. end;
  382. destructor TAsmSection.destroy;
  383. begin
  384. if assigned(Data) then
  385. Data.Free;
  386. relocations.free;
  387. end;
  388. function TAsmSection.write(var d;l:longint):longint;
  389. begin
  390. write:=datasize;
  391. if not assigned(Data) then
  392. Internalerror(3334441);
  393. Data.write(d,l);
  394. inc(datasize,l);
  395. end;
  396. function TAsmSection.writestr(const s:string):longint;
  397. begin
  398. writestr:=datasize;
  399. if not assigned(Data) then
  400. Internalerror(3334441);
  401. Data.write(s[1],length(s));
  402. inc(datasize,length(s));
  403. end;
  404. procedure TAsmSection.writealign(l:longint);
  405. var
  406. i : longint;
  407. empty : array[0..63] of char;
  408. begin
  409. { no alignment needed for 0 or 1 }
  410. if l<=1 then
  411. exit;
  412. i:=datasize mod l;
  413. if i>0 then
  414. begin
  415. if assigned(data) then
  416. begin
  417. fillchar(empty,sizeof(empty),0);
  418. Data.write(empty,l-i);
  419. end;
  420. inc(datasize,l-i);
  421. end;
  422. end;
  423. function TAsmSection.aligneddatasize:longint;
  424. begin
  425. aligneddatasize:=align(datasize,addralign);
  426. end;
  427. procedure TAsmSection.alignsection;
  428. begin
  429. writealign(addralign);
  430. end;
  431. procedure TAsmSection.alloc(l:longint);
  432. begin
  433. if assigned(Data) then
  434. Internalerror(3334442);
  435. inc(datasize,l);
  436. end;
  437. procedure TAsmSection.addsymreloc(ofs:longint;p:tasmsymbol;relative:TAsmRelocationType);
  438. var
  439. r : TAsmRelocation;
  440. begin
  441. r:=TAsmRelocation.Create;
  442. r.address:=ofs;
  443. r.orgsize:=0;
  444. r.symbol:=p;
  445. r.section:=sec_none;
  446. r.typ:=relative;
  447. relocations.concat(r);
  448. end;
  449. procedure TAsmSection.addsectionreloc(ofs:longint;sec:TSection;relative:TAsmRelocationType);
  450. var
  451. r : TAsmRelocation;
  452. begin
  453. r:=TAsmRelocation.Create;
  454. r.address:=ofs;
  455. r.symbol:=nil;
  456. r.orgsize:=0;
  457. r.section:=sec;
  458. r.typ:=relative;
  459. relocations.concat(r);
  460. end;
  461. {****************************************************************************
  462. TAsmObjectData
  463. ****************************************************************************}
  464. constructor TAsmObjectData.create(const n:string);
  465. begin
  466. inherited create;
  467. name:=n;
  468. { sections }
  469. FillChar(Sects,sizeof(Sects),0);
  470. { symbols }
  471. symbols:=tindexarray.create(symbolsgrow);
  472. symbols.noclear:=true;
  473. end;
  474. destructor TAsmObjectData.destroy;
  475. var
  476. sec : TSection;
  477. begin
  478. { free memory }
  479. for sec:=low(TSection) to high(TSection) do
  480. if assigned(sects[sec]) then
  481. sects[sec].free;
  482. symbols.free;
  483. end;
  484. procedure TAsmObjectData.createsection(sec:TSection);
  485. begin
  486. sects[sec]:=TAsmSection.create(target_asm.secnames[sec],1,(sec=sec_bss));
  487. end;
  488. function TAsmObjectData.sectionsize(s:TSection):longint;
  489. begin
  490. if assigned(sects[s]) then
  491. sectionsize:=sects[s].datasize
  492. else
  493. sectionsize:=0;
  494. end;
  495. function TAsmObjectData.currsectionsize:longint;
  496. begin
  497. if assigned(sects[currsec]) then
  498. currsectionsize:=sects[currsec].datasize
  499. else
  500. currsectionsize:=0;
  501. end;
  502. procedure TAsmObjectData.seTSectionsizes(var s:TAsmSectionSizes);
  503. begin
  504. end;
  505. procedure TAsmObjectData.defaulTSection(sec:TSection);
  506. begin
  507. currsec:=sec;
  508. end;
  509. procedure TAsmObjectData.writebytes(var data;len:longint);
  510. begin
  511. if not assigned(sects[currsec]) then
  512. createsection(currsec);
  513. sects[currsec].write(data,len);
  514. end;
  515. procedure TAsmObjectData.alloc(len:longint);
  516. begin
  517. if not assigned(sects[currsec]) then
  518. createsection(currsec);
  519. sects[currsec].alloc(len);
  520. end;
  521. procedure TAsmObjectData.allocalign(len:longint);
  522. var
  523. modulo : longint;
  524. begin
  525. if not assigned(sects[currsec]) then
  526. createsection(currsec);
  527. modulo:=sects[currsec].datasize mod len;
  528. if modulo > 0 then
  529. sects[currsec].alloc(len-modulo);
  530. end;
  531. procedure TAsmObjectData.fixuprelocs;
  532. begin
  533. { no relocation support by default }
  534. end;
  535. {****************************************************************************
  536. TAsmLibraryData
  537. ****************************************************************************}
  538. constructor TAsmLibraryData.create(const n:string);
  539. begin
  540. inherited create;
  541. name:=n;
  542. { symbols }
  543. symbolsearch:=tdictionary.create;
  544. symbolsearch.usehash;
  545. { labels }
  546. nextaltnr:=1;
  547. nextlabelnr:=1;
  548. { ppu }
  549. asmsymbolppuidx:=0;
  550. asmsymbolidx:=nil;
  551. end;
  552. destructor TAsmLibraryData.destroy;
  553. begin
  554. symbolsearch.free;
  555. Freeasmsymbolidx;
  556. end;
  557. procedure TAsmLibraryData.Freeasmsymbolidx;
  558. begin
  559. if assigned(asmsymbolidx) then
  560. begin
  561. Freemem(asmsymbolidx);
  562. asmsymbolidx:=nil;
  563. end;
  564. end;
  565. procedure TAsmLibraryData.DerefAsmsymbol(var s:tasmsymbol);
  566. begin
  567. if assigned(s) then
  568. begin
  569. if not assigned(asmsymbolidx) then
  570. internalerror(200208072);
  571. if (longint(pointer(s))<1) or (longint(pointer(s))>asmsymbolppuidx) then
  572. internalerror(200208073);
  573. s:=asmsymbolidx^[longint(pointer(s))-1];
  574. end;
  575. end;
  576. function TAsmLibraryData.newasmsymbol(const s : string) : tasmsymbol;
  577. var
  578. hp : tasmsymbol;
  579. begin
  580. hp:=tasmsymbol(symbolsearch.search(s));
  581. if not assigned(hp) then
  582. begin
  583. { Not found, insert it as an External }
  584. hp:=tasmsymbol.create(s,AB_EXTERNAL,AT_FUNCTION);
  585. symbolsearch.insert(hp);
  586. end;
  587. newasmsymbol:=hp;
  588. end;
  589. function TAsmLibraryData.newasmsymboltype(const s : string;_bind:TAsmSymBind;_typ:Tasmsymtype) : tasmsymbol;
  590. var
  591. hp : tasmsymbol;
  592. begin
  593. hp:=tasmsymbol(symbolsearch.search(s));
  594. if assigned(hp) then
  595. hp.defbind:=_bind
  596. else
  597. begin
  598. { Not found, insert it as an External }
  599. hp:=tasmsymbol.create(s,_bind,_typ);
  600. symbolsearch.insert(hp);
  601. end;
  602. newasmsymboltype:=hp;
  603. end;
  604. function TAsmLibraryData.getasmsymbol(const s : string) : tasmsymbol;
  605. begin
  606. getasmsymbol:=tasmsymbol(symbolsearch.search(s));
  607. end;
  608. function TAsmLibraryData.renameasmsymbol(const sold, snew : string):tasmsymbol;
  609. begin
  610. renameasmsymbol:=tasmsymbol(symbolsearch.rename(sold,snew));
  611. end;
  612. procedure TAsmLibraryData.CreateUsedAsmSymbolList;
  613. begin
  614. if assigned(usedasmsymbollist) then
  615. internalerror(78455782);
  616. usedasmsymbollist:=TSingleList.create;
  617. end;
  618. procedure TAsmLibraryData.DestroyUsedAsmSymbolList;
  619. begin
  620. usedasmsymbollist.destroy;
  621. usedasmsymbollist:=nil;
  622. end;
  623. procedure TAsmLibraryData.UsedAsmSymbolListInsert(p:tasmsymbol);
  624. begin
  625. if not p.inusedlist then
  626. usedasmsymbollist.insert(p);
  627. p.inusedlist:=true;
  628. end;
  629. procedure TAsmLibraryData.GenerateAltSymbol(p:tasmsymbol);
  630. begin
  631. if not assigned(p.altsymbol) then
  632. begin
  633. p.altsymbol:=tasmsymbol.create(name+'_'+tostr(nextaltnr),p.defbind,p.typ);
  634. symbolsearch.insert(p.altsymbol);
  635. { add also the original sym to the usedasmsymbollist,
  636. that list is used to reset the altsymbol }
  637. if not p.inusedlist then
  638. usedasmsymbollist.insert(p);
  639. p.inusedlist:=true;
  640. end;
  641. end;
  642. procedure TAsmLibraryData.UsedAsmSymbolListReset;
  643. var
  644. hp : tasmsymbol;
  645. begin
  646. hp:=tasmsymbol(usedasmsymbollist.first);
  647. while assigned(hp) do
  648. begin
  649. with hp do
  650. begin
  651. reset;
  652. inusedlist:=false;
  653. end;
  654. hp:=tasmsymbol(hp.listnext);
  655. end;
  656. end;
  657. procedure TAsmLibraryData.UsedAsmSymbolListResetAltSym;
  658. var
  659. hp : tasmsymbol;
  660. begin
  661. hp:=tasmsymbol(usedasmsymbollist.first);
  662. inc(nextaltnr);
  663. while assigned(hp) do
  664. begin
  665. with hp do
  666. begin
  667. altsymbol:=nil;
  668. inusedlist:=false;
  669. end;
  670. hp:=tasmsymbol(hp.listnext);
  671. end;
  672. end;
  673. procedure TAsmLibraryData.UsedAsmSymbolListCheckUndefined;
  674. var
  675. hp : tasmsymbol;
  676. begin
  677. hp:=tasmsymbol(usedasmsymbollist.first);
  678. while assigned(hp) do
  679. begin
  680. with hp do
  681. begin
  682. if is_used and
  683. (section=Sec_none) and
  684. not(currbind in [AB_EXTERNAL,AB_COMMON]) then
  685. Message1(asmw_e_undefined_label,name);
  686. end;
  687. hp:=tasmsymbol(hp.listnext);
  688. end;
  689. end;
  690. function TAsmLibraryData.newasmlabel(nr:longint;is_addr,is_data:boolean) : tasmlabel;
  691. var
  692. hp : tasmlabel;
  693. begin
  694. if is_addr then
  695. hp:=tasmlabel.createaddr(nr)
  696. else if is_data then
  697. hp:=tasmlabel.createdata(nr)
  698. else
  699. hp:=tasmlabel.create(nr);
  700. symbolsearch.insert(hp);
  701. newasmlabel:=hp;
  702. end;
  703. procedure TAsmLibraryData.getlabel(var l : tasmlabel);
  704. begin
  705. l:=tasmlabel.create(nextlabelnr);
  706. inc(nextlabelnr);
  707. symbolsearch.insert(l);
  708. end;
  709. procedure TAsmLibraryData.getdatalabel(var l : tasmlabel);
  710. begin
  711. l:=tasmlabel.createdata(nextlabelnr);
  712. inc(nextlabelnr);
  713. symbolsearch.insert(l);
  714. end;
  715. procedure TAsmLibraryData.getaddrlabel(var l : tasmlabel);
  716. begin
  717. l:=tasmlabel.createaddr(nextlabelnr);
  718. inc(nextlabelnr);
  719. symbolsearch.insert(l);
  720. end;
  721. procedure TAsmLibraryData.getlabelnr(var l : longint);
  722. begin
  723. l:=nextlabelnr;
  724. inc(nextlabelnr);
  725. end;
  726. end.
  727. {
  728. $Log$
  729. Revision 1.12 2002-11-17 16:31:55 carl
  730. * memory optimization (3-4%) : cleanup of tai fields,
  731. cleanup of tdef and tsym fields.
  732. * make it work for m68k
  733. Revision 1.11 2002/11/15 16:29:30 peter
  734. * made tasmsymbol.refs private (merged)
  735. Revision 1.10 2002/11/15 01:58:45 peter
  736. * merged changes from 1.0.7 up to 04-11
  737. - -V option for generating bug report tracing
  738. - more tracing for option parsing
  739. - errors for cdecl and high()
  740. - win32 import stabs
  741. - win32 records<=8 are returned in eax:edx (turned off by default)
  742. - heaptrc update
  743. - more info for temp management in .s file with EXTDEBUG
  744. Revision 1.9 2002/10/05 12:43:23 carl
  745. * fixes for Delphi 6 compilation
  746. (warning : Some features do not work under Delphi)
  747. Revision 1.8 2002/08/19 19:36:42 peter
  748. * More fixes for cross unit inlining, all tnodes are now implemented
  749. * Moved pocall_internconst to po_internconst because it is not a
  750. calling type at all and it conflicted when inlining of these small
  751. functions was requested
  752. Revision 1.7 2002/08/18 20:06:23 peter
  753. * inlining is now also allowed in interface
  754. * renamed write/load to ppuwrite/ppuload
  755. * tnode storing in ppu
  756. * nld,ncon,nbas are already updated for storing in ppu
  757. Revision 1.6 2002/08/12 15:08:39 carl
  758. + stab register indexes for powerpc (moved from gdb to cpubase)
  759. + tprocessor enumeration moved to cpuinfo
  760. + linker in target_info is now a class
  761. * many many updates for m68k (will soon start to compile)
  762. - removed some ifdef or correct them for correct cpu
  763. Revision 1.5 2002/08/11 14:32:25 peter
  764. * renamed current_library to objectlibrary
  765. Revision 1.4 2002/08/11 13:24:10 peter
  766. * saving of asmsymbols in ppu supported
  767. * asmsymbollist global is removed and moved into a new class
  768. tasmlibrarydata that will hold the info of a .a file which
  769. corresponds with a single module. Added librarydata to tmodule
  770. to keep the library info stored for the module. In the future the
  771. objectfiles will also be stored to the tasmlibrarydata class
  772. * all getlabel/newasmsymbol and friends are moved to the new class
  773. Revision 1.3 2002/07/10 07:24:40 jonas
  774. * memory leak fixes from Sergey Korshunoff
  775. Revision 1.2 2002/07/07 09:52:32 florian
  776. * powerpc target fixed, very simple units can be compiled
  777. * some basic stuff for better callparanode handling, far from being finished
  778. Revision 1.1 2002/07/01 18:46:20 peter
  779. * internal linker
  780. * reorganized aasm layer
  781. }