123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 |
- {
- Copyright (c) 1998-2006 by Peter Vreman
- Includes ELF-related code specific to x86_64
- 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 cpuelf;
- {$i fpcdefs.inc}
- interface
- implementation
- uses
- globtype,cutils,cclasses,
- verbose,elfbase,
- systems,aasmbase,ogbase,ogelf,assemble;
- type
- TElfExeOutputx86_64=class(TElfExeOutput)
- private
- procedure MaybeWriteGOTEntry(reltyp:byte;relocval:aint;objsym:TObjSymbol);
- protected
- procedure WriteFirstPLTEntry;override;
- procedure WritePLTEntry(exesym:TExeSymbol);override;
- procedure WriteIndirectPLTEntry(exesym:TExeSymbol);override;
- procedure GOTRelocPass1(objsec:TObjSection;var idx:longint);override;
- procedure DoRelocationFixup(objsec:TObjSection);override;
- end;
- const
- { Relocation types }
- R_X86_64_NONE = 0;
- R_X86_64_64 = 1; { Direct 64 bit }
- R_X86_64_PC32 = 2; { PC relative 32 bit signed }
- R_X86_64_GOT32 = 3; { 32 bit GOT entry }
- R_X86_64_PLT32 = 4; { 32 bit PLT address }
- R_X86_64_COPY = 5; { Copy symbol at runtime }
- R_X86_64_GLOB_DAT = 6; { Create GOT entry }
- R_X86_64_JUMP_SLOT = 7; { Create PLT entry }
- R_X86_64_RELATIVE = 8; { Adjust by program base }
- R_X86_64_GOTPCREL = 9; { 32 bit signed PC relative offset to GOT }
- R_X86_64_32 = 10; { Direct 32 bit zero extended }
- R_X86_64_32S = 11; { Direct 32 bit sign extended }
- R_X86_64_16 = 12; { Direct 16 bit zero extended }
- R_X86_64_PC16 = 13; { 16 bit sign extended PC relative }
- R_X86_64_8 = 14; { Direct 8 bit sign extended }
- R_X86_64_PC8 = 15; { 8 bit sign extended PC relative }
- R_X86_64_DTPMOD64 = 16; { ID of module containing symbol }
- R_X86_64_DTPOFF64 = 17; { Offset in module's TLS block }
- R_X86_64_TPOFF64 = 18; { Offset in initial TLS block }
- { 32 bit signed PC relative offset to two GOT entries for GD symbol }
- R_X86_64_TLSGD = 19;
- { 32 bit signed PC relative offset to two GOT entries for LD symbol }
- R_X86_64_TLSLD = 20;
- R_X86_64_DTPOFF32 = 21; { Offset in TLS block }
- { 32 bit signed PC relative offset to GOT entry for IE symbol }
- R_X86_64_GOTTPOFF = 22;
- R_X86_64_TPOFF32 = 23; { Offset in initial TLS block }
- R_X86_64_PC64 = 24; { PC relative 64-bit signed }
- R_X86_64_GOTOFF64 = 25; { 64-bit offset from GOT base }
- R_X86_64_GOTPC32 = 26; { PC-relative offset GOT }
- R_X86_64_GOT64 = 27; { 64-bit GOT entry offset }
- R_X86_64_GOTPCREL64 = 28; { 64-bit PC relative offset to GOT entry }
- R_X86_64_GOTPC64 = 29; { 64-bit PC relative offset to GOT }
- R_X86_64_GOTPLT64 = 30; { Like GOT64, indicates that PLT entry needed }
- R_X86_64_PLTOFF64 = 31; { 64-bit GOT relative offset to PLT entry }
- R_X86_64_SIZE32 = 32;
- R_X86_64_SIZE64 = 33;
- R_X86_64_GOTPC32_TLSDESC = 34;
- R_X86_64_TLSDESC_CALL = 35;
- R_X86_64_TLSDESC = 36;
- R_X86_64_IRELATIVE = 37;
- R_X86_64_GNU_VTINHERIT = 250; { GNU extension to record C++ vtable hierarchy }
- R_X86_64_GNU_VTENTRY = 251; { GNU extension to record C++ vtable member usage }
- type
- TRelocProp=record
- name: PChar;
- size: byte;
- end;
- const
- relocprops: array[0..37] of TRelocProp=(
- (name: 'R_X86_64_NONE'; size:0),
- (name: 'R_X86_64_64'; size:8),
- (name: 'R_X86_64_PC32'; size:4),
- (name: 'R_X86_64_GOT32'; size:4),
- (name: 'R_X86_64_PLT32'; size:4),
- (name: 'R_X86_64_COPY'; size:0),
- (name: 'R_X86_64_GLOB_DAT'; size:8),
- (name: 'R_X86_64_JUMP_SLOT';size:8),
- (name: 'R_X86_64_RELATIVE'; size:8),
- (name: 'R_X86_64_GOTPCREL'; size:4),
- (name: 'R_X86_64_32'; size:4),
- (name: 'R_X86_64_32S'; size:4),
- (name: 'R_X86_64_16'; size:2),
- (name: 'R_X86_64_PC16'; size:2),
- (name: 'R_X86_64_8'; size:1),
- (name: 'R_X86_64_PC8'; size:1),
- (name: 'R_X86_64_DTPMOD64'; size:8),
- (name: 'R_X86_64_DTPOFF64'; size:8),
- (name: 'R_X86_64_TPOFF64'; size:8),
- (name: 'R_X86_64_TLSGD'; size:4),
- (name: 'R_X86_64_TLSLD'; size:4),
- (name: 'R_X86_64_DTPOFF32'; size:4),
- (name: 'R_X86_64_GOTTPOFF'; size:4),
- (name: 'R_X86_64_TPOFF32'; size:4),
- (name: 'R_X86_64_PC64'; size:8),
- (name: 'R_X86_64_GOTOFF64'; size:8),
- (name: 'R_X86_64_GOTPC32'; size:4),
- (name: 'R_X86_64_GOT64'; size:8),
- (name: 'R_X86_64_GOTPCREL64'; size:8),
- (name: 'R_X86_64_GOTPC64'; size:8),
- (name: 'R_X86_64_GOTPLT64'; size:8),
- (name: 'R_X86_64_PLTOFF64'; size:8),
- (name: 'R_X86_64_SIZE32'; size:4),
- (name: 'R_X86_64_SIZE64'; size:8),
- (name: 'R_X86_64_GOTPC32_TLSDESC'; size:4),
- (name: 'R_X86_64_TLSDESC_CALL'; size:0),
- (name: 'R_X86_64_TLSDESC'; size:8),
- (name: 'R_X86_64_IRELATIVE'; size:8)
- );
- {****************************************************************************
- ELF Target methods
- ****************************************************************************}
- function elf_x86_64_encodereloc(objrel:TObjRelocation):byte;
- begin
- case objrel.typ of
- RELOC_NONE :
- result:=R_X86_64_NONE;
- { Note: 8 and 16-bit relocations are known to be non-conformant with
- AMD64 ABI, so they aren't handled. }
- RELOC_RELATIVE :
- if objrel.size=8 then
- result:=R_X86_64_PC64
- else if objrel.size=4 then
- result:=R_X86_64_PC32
- else
- InternalError(2012061900);
- RELOC_ABSOLUTE :
- if objrel.size=8 then
- result:=R_X86_64_64
- else if objrel.size=4 then
- result:=R_X86_64_32
- else
- InternalError(2012061901);
- RELOC_ABSOLUTE32 :
- result:=R_X86_64_32S;
- RELOC_GOTPCREL :
- result:=R_X86_64_GOTPCREL;
- RELOC_PLT32 :
- result:=R_X86_64_PLT32;
- else
- result:=0;
- InternalError(2012082302);
- end;
- end;
- procedure elf_x86_64_loadreloc(objrel:TObjRelocation);
- begin
- end;
- function elf_x86_64_relocname(reltyp:byte):string;
- begin
- if reltyp<=high(relocprops) then
- result:=relocprops[reltyp].name
- else
- result:='unknown ('+tostr(reltyp)+')';
- end;
- {****************************************************************************
- TELFExeOutputx86_64
- ****************************************************************************}
- procedure TElfExeOutputx86_64.GOTRelocPass1(objsec:TObjSection;var idx:longint);
- var
- objsym:TObjSymbol;
- objreloc:TObjRelocation;
- reltyp:byte;
- begin
- objreloc:=TObjRelocation(objsec.ObjRelocations[idx]);
- if (ObjReloc.flags and rf_raw)=0 then
- reltyp:=ElfTarget.encodereloc(ObjReloc)
- else
- reltyp:=ObjReloc.ftype;
- case reltyp of
- R_X86_64_PLT32,
- R_X86_64_PLTOFF64,
- R_X86_64_GOTPLT64:
- begin
- objsym:=ObjReloc.symbol.exesymbol.ObjSymbol;
- objsym.refs:=objsym.refs or symref_plt;
- end;
- end;
- case reltyp of
- R_X86_64_GOTTPOFF:
- begin
- { TLS IE to locally defined symbol, convert into LE so GOT entry isn't needed
- (Is TLS IE allowed in shared libs at all? Yes it is, when lib is accessing
- a threadvar in main program or in other *statically* loaded lib; TLS IE access to
- own threadvars may render library not loadable dynamically) }
- (*
- if not (IsSharedLibrary or (sym.dynindex>0)) then
- begin
- if not IsValidIEtoLE(objsec,ObjReloc) then
- Comment(v_error,'Cannot transform TLS IE to LE');
- TranslateIEtoLE(objsec,ObjReloc);
- ObjReloc.ftype:=R_X86_64_TPOFF32;
- exit;
- end;
- *)
- AllocGOTSlot(objreloc.symbol);
- end;
- R_X86_64_GOT32,
- R_X86_64_GOT64,
- R_X86_64_GOTPCREL,
- R_X86_64_GOTPCREL64:
- begin
- if AllocGOTSlot(objreloc.symbol) then
- if IsSharedLibrary and (objreloc.symbol.exesymbol.dynindex=0) then
- Inc(relative_reloc_count);
- end;
- //R_X86_64_TLSGD,
- //R_X86_64_TLSLD: { TODO: allocate two GOT slots }
- { R_X86_64_32S cannot be used in DSOs at all }
- R_X86_64_32S:
- if IsSharedLibrary then
- ReportNonDSOReloc(reltyp,objsec,objreloc);
- { R_X86_64_32 is processed by rtld, but binutils accept it in data sections only.
- Relocating the against local symbols is tricky: changing into RELATIVE is not possible,
- so it is changed into relocation against section symbol. This requires adding
- the appropriate section symbol to dynamic symtable. BFD also has some obscure logic
- behind, e.g. it uses .text section for symbols from .data section.
- For now, leave this situation unhandled, as 32-bit relocations aren't commonly
- used in 64-bit code. }
- R_X86_64_32:
- if IsSharedLibrary then
- begin
- if (oso_executable in objsec.SecOptions) or
- not (oso_write in objsec.SecOptions) then
- ReportNonDSOReloc(reltyp,objsec,objreloc)
- else
- InternalError(2012092601);
- end;
- R_X86_64_64:
- begin
- if IsSharedLibrary then
- begin
- if (oso_executable in objsec.SecOptions) or
- not (oso_write in objsec.SecOptions) then
- hastextrelocs:=True;
- dynrelocsec.alloc(dynrelocsec.shentsize);
- objreloc.flags:=objreloc.flags or rf_dynamic;
- if (objreloc.symbol=nil) or
- (objreloc.symbol.exesymbol=nil) or
- (objreloc.symbol.exesymbol.dynindex=0) then
- Inc(relative_reloc_count);
- end;
- end;
- end;
- end;
- procedure TElfExeOutputx86_64.MaybeWriteGOTEntry(reltyp:byte;relocval:aint;objsym:TObjSymbol);
- var
- gotoff,tmp:aword;
- begin
- gotoff:=objsym.exesymbol.gotoffset;
- if gotoff=0 then
- InternalError(2012060902);
- { the GOT slot itself, and a dynamic relocation for it }
- { TODO: only data symbols must get here }
- if gotoff=gotobjsec.Data.size+sizeof(pint) then
- begin
- gotobjsec.write(relocval,sizeof(pint));
- tmp:=gotobjsec.mempos+gotoff-sizeof(pint);
- if (objsym.exesymbol.dynindex>0) then
- begin
- if (reltyp=R_X86_64_GOTTPOFF) then
- if IsSharedLibrary then
- dynreloclist.Add(TObjRelocation.CreateRaw(tmp,objsym,R_X86_64_TPOFF64)) // probably incorrect
- else
- else
- dynreloclist.Add(TObjRelocation.CreateRaw(tmp,objsym,R_X86_64_GLOB_DAT));
- end
- else if IsSharedLibrary then
- WriteDynRelocEntry(tmp,R_X86_64_RELATIVE,0,relocval);
- end;
- end;
- procedure TElfExeOutputx86_64.DoRelocationFixup(objsec:TObjSection);
- var
- i,zero:longint;
- objreloc: TObjRelocation;
- address,
- relocval : aint;
- relocsec : TObjSection;
- data: TDynamicArray;
- reltyp,relsize: byte;
- PC: aword;
- begin
- data:=objsec.data;
- for i:=0 to objsec.ObjRelocations.Count-1 do
- begin
- objreloc:=TObjRelocation(objsec.ObjRelocations[i]);
- case objreloc.typ of
- RELOC_NONE:
- continue;
- RELOC_ZERO:
- begin
- data.Seek(objreloc.dataoffset);
- zero:=0;
- data.Write(zero,4);
- continue;
- end;
- end;
- if (objreloc.flags and rf_raw)=0 then
- reltyp:=ElfTarget.encodereloc(objreloc)
- else
- reltyp:=objreloc.ftype;
- if reltyp<=high(relocprops) then
- relsize:=relocprops[reltyp].size
- else
- InternalError(2012092103);
- if ElfTarget.relocs_use_addend then
- address:=objreloc.orgsize
- else
- begin
- data.Seek(objreloc.dataoffset);
- data.Read(address,relsize);
- end;
- if assigned(objreloc.symbol) then
- begin
- relocsec:=objreloc.symbol.objsection;
- relocval:=objreloc.symbol.address;
- end
- else if assigned(objreloc.objsection) then
- begin
- relocsec:=objreloc.objsection;
- relocval:=objreloc.objsection.mempos
- end
- else
- internalerror(2012060702);
- { Only debug sections are allowed to have relocs pointing to unused sections }
- if assigned(relocsec) and not (relocsec.used and assigned(relocsec.exesection)) and
- not (oso_debug in objsec.secoptions) then
- begin
- writeln(objsec.fullname,' references ',relocsec.fullname);
- internalerror(2012060703);
- end;
- PC:=objsec.mempos+objreloc.dataoffset;
- { TODO: if relocsec=nil, relocations must be copied to .rela.dyn section }
- if (relocsec=nil) or (relocsec.used) then
- case reltyp of
- R_X86_64_PC32,
- R_X86_64_PC64:
- begin
- // TODO: ld rejects PC32 relocations to dynamic symbols, they must use @PLT
- address:=address+relocval-PC;
- end;
- R_X86_64_PLT32:
- begin
- { If target is in current object, treat as RELOC_RELATIVE }
- address:=address+relocval-PC;
- end;
- R_X86_64_TPOFF32,
- R_X86_64_TPOFF64:
- address:=relocval-(tlsseg.MemPos+tlsseg.MemSize);
- R_X86_64_GOTTPOFF,
- R_X86_64_GOTPCREL,
- R_X86_64_GOTPCREL64:
- begin
- if (reltyp=R_X86_64_GOTTPOFF) then
- relocval:=relocval-(tlsseg.MemPos+tlsseg.MemSize);
- MaybeWriteGOTEntry(reltyp,relocval,objreloc.symbol);
- { resolves to PC-relative offset to GOT slot }
- relocval:=gotobjsec.mempos+objreloc.symbol.exesymbol.gotoffset-sizeof(pint);
- address:=address+relocval-PC;
- end;
- R_X86_64_32S,
- R_X86_64_32:
- inc(address,relocval);
- R_X86_64_64:
- begin
- inc(address,relocval);
- if (objreloc.flags and rf_dynamic)<>0 then
- begin
- if (objreloc.symbol=nil) or
- (objreloc.symbol.exesymbol=nil) or
- (objreloc.symbol.exesymbol.dynindex=0) then
- WriteDynRelocEntry(PC,R_X86_64_RELATIVE,0,address)
- else
- dynreloclist.add(TObjRelocation.CreateRaw(PC,objreloc.symbol,R_X86_64_64));
- end;
- end;
- R_X86_64_GOTPC32,
- R_X86_64_GOTPC64:
- begin
- address:=address+gotsymbol.address-PC;
- end;
- R_X86_64_GOT32,
- R_X86_64_GOT64:
- begin
- MaybeWriteGOTEntry(reltyp,relocval,objreloc.symbol);
- relocval:=gotobjsec.mempos+objreloc.symbol.exesymbol.gotoffset-sizeof(pint)-gotsymbol.address;
- address:=address+relocval;
- end;
- R_X86_64_GOTOFF64,
- R_X86_64_PLTOFF64:
- begin
- address:=address+relocval-gotsymbol.address;
- end;
- else
- begin
- writeln(objreloc.typ);
- internalerror(200604014);
- end;
- end
- else { not relocsec.Used }
- address:=0; { Relocation in debug section points to unused section, which is eliminated by linker }
- case relsize of
- 8: ;
- 4:
- begin
- case reltyp of
- R_X86_64_32:
- if qword(address)>qword($FFFFFFFF) then
- ReportRelocOverflow(reltyp,objsec,objreloc);
- else
- if (address>high(longint)) or (address<low(longint)) then
- ReportRelocOverflow(reltyp,objsec,objreloc);
- end;
- end;
- else
- InternalError(2012101102);
- end;
- data.Seek(objreloc.dataoffset);
- data.Write(address,relsize);
- end;
- end;
- procedure TElfExeOutputx86_64.WriteFirstPLTEntry;
- begin
- pltobjsec.writeBytes(#$FF#$35); // push got+8(%rip)
- pltobjsec.writeReloc_internal(gotpltobjsec,sizeof(pint),4,RELOC_RELATIVE);
- pltobjsec.writeBytes(#$FF#$25); // jmp *got+16(%rip)
- pltobjsec.writeReloc_internal(gotpltobjsec,2*sizeof(pint),4,RELOC_RELATIVE);
- pltobjsec.writeBytes(#$0F#$1F#$40#$00); // nopl 0(%rax)
- end;
- procedure TElfExeOutputx86_64.WritePLTEntry(exesym:TExeSymbol);
- var
- got_offset: aword;
- tmp: pint;
- begin
- pltobjsec.writeBytes(#$FF#$25); // jmp *got+x(%rip)
- pltobjsec.writeReloc_internal(gotpltobjsec,gotpltobjsec.size,4,RELOC_RELATIVE);
- pltobjsec.writeBytes(#$68); // push $index
- tmp:=pltrelocsec.size div pltrelocsec.shentsize;
- pltobjsec.write(tmp,4);
- pltobjsec.writeBytes(#$E9); // jmp .plt
- tmp:=-(4+pltobjsec.Size);
- pltobjsec.write(tmp,4);
- { write a .got.plt slot pointing back to the 'push' instruction }
- gotpltobjsec.writeReloc_internal(pltobjsec,pltobjsec.size-(16-6),sizeof(pint),RELOC_ABSOLUTE);
- { write a .rela.plt entry (Elf64_rela record) }
- pltrelocsec.writeReloc_internal(gotpltobjsec,gotpltobjsec.size-sizeof(pint),sizeof(pint),RELOC_ABSOLUTE);
- got_offset:=(qword(exesym.dynindex) shl 32) or R_X86_64_JUMP_SLOT;
- pltrelocsec.write(got_offset,sizeof(pint));
- if ElfTarget.relocs_use_addend then
- pltrelocsec.writezeros(sizeof(pint));
- end;
- procedure TElfExeOutputx86_64.WriteIndirectPLTEntry(exesym:TExeSymbol);
- var
- tmp: pint;
- objsym:TObjSymbol;
- targetsym:TObjSymbol;
- begin
- targetsym:=exesym.ObjSymbol;
- objsym:=internalobjdata.CreateSymbol(exesym.name);
- objsym.typ:=AT_FUNCTION;
- objsym.bind:=exesym.ObjSymbol.bind; { AB_EXTERNAL or AB_WEAK_EXTERNAL }
- objsym.offset:=pltobjsec.size;
- objsym.objsection:=pltobjsec;
- exesym.ObjSymbol:=objsym;
- pltobjsec.writeBytes(#$FF#$25); // jmp *got+x(%rip)
- pltobjsec.writeReloc_internal(gotpltobjsec,gotpltobjsec.size,4,RELOC_RELATIVE);
- { TODO: Are these entries relevant when linking dynamic?
- (for static linking, they don't matter) }
- pltobjsec.writeBytes(#$68); // push $index
- tmp:=pltrelocsec.size div pltrelocsec.shentsize;
- pltobjsec.write(tmp,4);
- pltobjsec.writeBytes(#$E9); // jmp .plt
- tmp:=-(4+pltobjsec.Size);
- pltobjsec.write(tmp,4);
- { write a .got.plt slot pointing back to the 'push' instruction }
- gotpltobjsec.writeReloc_internal(pltobjsec,pltobjsec.size-(16-6),sizeof(pint),RELOC_ABSOLUTE);
- { write a .rela.iplt entry (Elf64_rela record) }
- ipltrelocsec.writeReloc_internal(gotpltobjsec,gotpltobjsec.size-sizeof(pint),sizeof(pint),RELOC_ABSOLUTE);
- tmp:=R_X86_64_IRELATIVE;
- ipltrelocsec.write(tmp,sizeof(pint));
- if ElfTarget.relocs_use_addend then
- ipltrelocsec.writeReloc_internal(targetsym.objsection,targetsym.offset,sizeof(pint),RELOC_ABSOLUTE);
- end;
- {*****************************************************************************
- Initialize
- *****************************************************************************}
- const
- elf_target_x86_64: TElfTarget =
- (
- max_page_size: $200000;
- exe_image_base: $400000;
- machine_code: EM_X86_64;
- relocs_use_addend: true;
- dyn_reloc_codes: (
- R_X86_64_RELATIVE,
- R_X86_64_GLOB_DAT,
- R_X86_64_JUMP_SLOT,
- R_X86_64_COPY,
- R_X86_64_IRELATIVE
- );
- relocname: @elf_x86_64_relocName;
- encodereloc: @elf_x86_64_encodeReloc;
- loadreloc: @elf_x86_64_loadReloc;
- loadsection: nil;
- );
- as_x86_64_elf64_info : tasminfo =
- (
- id : as_x86_64_elf64;
- idtxt : 'ELF';
- asmbin : '';
- asmcmd : '';
- supported_targets : [system_x86_64_linux,system_x86_64_freebsd,
- system_x86_64_openbsd,system_x86_64_netbsd];
- flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf];
- labelprefix : '.L';
- comment : '';
- dollarsign: '$';
- );
- initialization
- RegisterAssembler(as_x86_64_elf64_info,TElfAssembler);
- ElfTarget:=elf_target_x86_64;
- ElfExeOutputClass:=TElfExeOutputx86_64;
- end.
|