123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- {
- $Id$
- Copyright (c) 2002 by Daniel Mantione, Peter Vreman
- Contains the binary reader and writer for the linear executable
- format used by OS/2
- * This code was inspired by the NASM sources
- The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- Julian Hall. All rights reserved.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- unit oglx;
- {$i fpcdefs.inc}
- interface
- uses
- { common }
- cclasses,
- { target }
- systems,
- { assembler }
- cpubase,aasmbase,assemble,link,
- { output }
- ogbase,ogmap,ogcoff;
- type Tlxheader = packed record
- magic:word; {'LX'}
- byteorder:byte; {0 = little 1 = big endian}
- wordorder:byte;
- cpu_type:word;
- os_type:word;
- module_version:cardinal;
- module_flags:cardinal;
- module_page_count:cardinal;
- eip_object,eip:cardinal;
- esp_object,esp:cardinal;
- page_size,page_shift:cardinal;
- fixup_sect_size:cardinal;
- fixup_sect_checksum:cardinal;
- loader_sect_size:cardinal;
- loader_sect_chksum:cardinal;
- object_table_offset:cardinal;
- object_count:cardinal;
- object_pagetable_ofs:cardinal;
- object_iterpages_ofs:cardinal;
- resource_table_ofs:cardinal;
- resource_count:cardinal;
-
- end;
- Tlxexeoutput = class(texeoutput)
- private
- { FCoffsyms,
- FCoffStrs : tdynamicarray;
- win32 : boolean;}
- nsects,
- nsyms,
- sympos : longint;
- procedure write_symbol(const name:string;strpos,value,section,typ,aux:longint);
- procedure write_symbols;
- protected
- function writedata:boolean;override;
- public
- constructor createos2;
- function newobjectinput:tobjectinput;override;
- procedure CalculateMemoryMap;override;
- procedure GenerateExecutable(const fn:string);override;
- end;
- tlxlinker = class(tinternallinker)
- constructor create;override;
- end;
- implementation
- uses
- {$ifdef delphi}
- sysutils,
- {$else}
- strings,
- {$endif}
- cutils,verbose,
- globtype,globals,fmodule;
- {****************************************************************************
- tcoffexeoutput
- ****************************************************************************}
- constructor Tlxexeoutput.createos2;
- begin
- inherited create;
- end;
- function Tlxexeoutput.newobjectinput:tobjectinput;
- begin
- result:=tcoffobjectinput.createdjgpp;
- end;
- procedure Tlxexeoutput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
- { var
- sym : coffsymbol;}
- begin
- { FillChar(sym,sizeof(sym),0);
- if strpos=-1 then
- move(name[1],sym.name,length(name))
- else
- sym.strpos:=strpos;
- sym.value:=value;
- sym.section:=section;
- sym.typ:=typ;
- sym.aux:=aux;
- FWriter.write(sym,sizeof(sym));}
- end;
- procedure Tlxexeoutput.write_symbols;
- { var
- filename : string[18];
- sec : TSection;
- namestr : string[8];
- nameidx,
- value,
- sectionval,
- i : longint;
- globalval : byte;
- secrec : coffsectionrec;
- objdata : TAsmObjectData;
- p : tasmsymbol;
- s : string;}
- begin
- (* objdata:=TAsmObjectData(objdatalist.first);
- while assigned(objdata) do
- begin
- with tcoffobjectdata(objdata) do
- begin
- { The symbols used }
- p:=Tasmsymbol(symbols.First);
- while assigned(p) do
- begin
- if p.section=sec_common then
- sectionval:=sections[sec_bss].secsymidx
- else
- sectionval:=sections[p.section].secsymidx;
- if p.currbind=AB_LOCAL then
- globalval:=3
- else
- globalval:=2;
- { if local of global then set the section value to the address
- of the symbol }
- if p.currbind in [AB_LOCAL,AB_GLOBAL] then
- value:=p.address
- else
- value:=p.size;
- { symbolname }
- s:=p.name;
- if length(s)>8 then
- begin
- nameidx:=FCoffStrs.size+4;
- FCoffStrs.writestr(s);
- FCoffStrs.writestr(#0);
- end
- else
- begin
- nameidx:=-1;
- namestr:=s;
- end;
- write_symbol(namestr,nameidx,value,sectionval,globalval,0);
- p:=tasmsymbol(p.indexnext);
- end;
- end;
- objdata:=TAsmObjectData(objdata.next);
- end;*)
- end;
- procedure Tlxexeoutput.CalculateMemoryMap;
- { var
- objdata : TAsmObjectData;
- secsymidx,
- mempos,
- datapos : longint;
- sec : TSection;
- sym : tasmsymbol;
- s : TAsmSection;}
- begin
- (* { retrieve amount of sections }
- nsects:=0;
- secsymidx:=0;
- for sec:=low(TSection) to high(TSection) do
- begin
- if sections[sec].available then
- begin
- inc(nsects);
- inc(secsymidx);
- sections[sec].secsymidx:=secsymidx;
- end;
- end;
- { calculate start positions after the headers }
- datapos:=sizeof(coffheader)+sizeof(coffoptheader)+sizeof(coffsechdr)*nsects;
- mempos:=sizeof(coffheader)+sizeof(coffoptheader)+sizeof(coffsechdr)*nsects;
- if not win32 then
- inc(mempos,sizeof(go32v2stub)+$1000);
- { add sections }
- MapObjectdata(datapos,mempos);
- { end symbol }
- AddGlobalSym('_etext',sections[sec_code].mempos+sections[sec_code].memsize);
- AddGlobalSym('_edata',sections[sec_data].mempos+sections[sec_data].memsize);
- AddGlobalSym('end',mempos);
- { symbols }
- nsyms:=0;
- sympos:=0;
- if not(cs_link_strip in aktglobalswitches) then
- begin
- sympos:=datapos;
- objdata:=TAsmObjectData(objdatalist.first);
- while assigned(objdata) do
- begin
- inc(nsyms,objdata.symbols.count);
- objdata:=TAsmObjectData(objdata.next);
- end;
- end;*)
- end;
- function Tlxexeoutput.writedata:boolean;
- { var
- datapos,
- secsymidx,
- i : longint;
- hstab : coffstab;
- gotreloc : boolean;
- sec : TSection;
- header : coffheader;
- optheader : coffoptheader;
- sechdr : coffsechdr;
- empty : array[0..15] of byte;
- hp : pdynamicblock;
- objdata : TAsmObjectData;
- hsym : tasmsymbol;}
- begin
- (* result:=false;
- FCoffSyms:=TDynamicArray.Create(symbolresize);
- FCoffStrs:=TDynamicArray.Create(strsresize);
- { Stub }
- if not win32 then
- FWriter.write(go32v2stub,sizeof(go32v2stub));
- { COFF header }
- fillchar(header,sizeof(header),0);
- header.mach:=$14c;
- header.nsects:=nsects;
- header.sympos:=sympos;
- header.syms:=nsyms;
- header.opthdr:=sizeof(coffoptheader);
- header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_EXE or COFF_FLAG_NORELOCS or COFF_FLAG_NOLINES;
- FWriter.write(header,sizeof(header));
- { Optional COFF Header }
- fillchar(optheader,sizeof(optheader),0);
- optheader.magic:=$10b;
- optheader.tsize:=sections[sec_code].memsize;
- optheader.dsize:=sections[sec_data].memsize;
- optheader.bsize:=sections[sec_bss].memsize;
- hsym:=tasmsymbol(globalsyms.search('start'));
- if not assigned(hsym) then
- begin
- Comment(V_Error,'Entrypoint "start" not defined');
- exit;
- end;
- optheader.entry:=hsym.address;
- optheader.text_start:=sections[sec_code].mempos;
- optheader.data_start:=sections[sec_data].mempos;
- FWriter.write(optheader,sizeof(optheader));
- { Section headers }
- for sec:=low(TSection) to high(TSection) do
- if sections[sec].available then
- begin
- fillchar(sechdr,sizeof(sechdr),0);
- move(target_asm.secnames[sec][1],sechdr.name,length(target_asm.secnames[sec]));
- if not win32 then
- begin
- sechdr.rvaofs:=sections[sec].mempos;
- sechdr.vsize:=sections[sec].mempos;
- end
- else
- begin
- if sec=sec_bss then
- sechdr.vsize:=sections[sec].memsize;
- end;
- if sec=sec_bss then
- sechdr.datasize:=sections[sec].memsize
- else
- begin
- sechdr.datasize:=sections[sec].datasize;
- sechdr.datapos:=sections[sec].datapos;
- end;
- sechdr.nrelocs:=0;
- sechdr.relocpos:=0;
- sechdr.flags:=sections[sec].flags;
- FWriter.write(sechdr,sizeof(sechdr));
- end;
- { Sections }
- for sec:=low(TSection) to high(TSection) do
- if sections[sec].available then
- begin
- { update objectfiles }
- objdata:=TAsmObjectData(objdatalist.first);
- while assigned(objdata) do
- begin
- if assigned(objdata.sects[sec]) and
- assigned(objdata.sects[sec].data) then
- begin
- WriteZeros(objdata.sects[sec].dataalignbytes);
- hp:=objdata.sects[sec].data.firstblock;
- while assigned(hp) do
- begin
- FWriter.write(hp^.data,hp^.used);
- hp:=hp^.next;
- end;
- end;
- objdata:=TAsmObjectData(objdata.next);
- end;
- end;
- { Optional symbols }
- if not(cs_link_strip in aktglobalswitches) then
- begin
- { Symbols }
- write_symbols;
- { Strings }
- i:=FCoffStrs.size+4;
- FWriter.write(i,4);
- hp:=FCoffStrs.firstblock;
- while assigned(hp) do
- begin
- FWriter.write(hp^.data,hp^.used);
- hp:=hp^.next;
- end;
- end;
- { Release }
- FCoffStrs.Free;
- FCoffSyms.Free;
- result:=true;*)
- end;
- procedure Tlxexeoutput.GenerateExecutable(const fn:string);
- begin
- { AddGlobalSym('_etext',0);
- AddGlobalSym('_edata',0);
- AddGlobalSym('end',0);
- if not CalculateSymbols then
- exit;
- CalculateMemoryMap;
- FixupSymbols;
- FixupRelocations;
- writeexefile(fn);}
- end;
- {****************************************************************************
- TCoffLinker
- ****************************************************************************}
- constructor Tlxlinker.Create;
- begin
- inherited Create;
- exeoutput:=Tlxexeoutput.createos2;
- end;
- {*****************************************************************************
- Initialize
- *****************************************************************************}
- begin
- { RegisterAssembler(as_i386_coff_info,TCoffAssembler);
- RegisterAssembler(as_i386_pecoff_info,TPECoffAssembler);
- RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);}
- RegisterLinker(ld_i386_coff,Tlxlinker);
- end.
- {
- $Log$
- Revision 1.1 2002-07-08 19:22:22 daniel
- + OS/2 lx format support: Copied ogcoff and started to modify it
- }
|