aasmbase.pas 28 KB

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