dmd/src/ddmd/backend/obj.d

416 lines
18 KiB
D

/**
* Compiler implementation of the
* $(LINK2 http://www.dlang.org, D programming language).
*
* Copyright: Copyright (C) 1994-1998 by Symantec
* Copyright (c) 2000-2017 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/ddmd/backend/obj.d, backend/obj.d)
*/
module ddmd.backend.obj;
// Online documentation: https://dlang.org/phobos/ddmd_backend_obj.html
/* Interface to object file format
*/
import ddmd.backend.cdef;
import ddmd.backend.cc;
import ddmd.backend.code;
import ddmd.backend.el;
import ddmd.backend.outbuf;
extern (C++):
version (Windows)
{
version (SCPP)
{
version = OMF;
}
version (SPP)
{
version = OMF;
}
version (HTOD)
{
version = STUB;
}
version (MARS)
{
version = OMFandMSCOFF;
}
}
version (OMF)
{
class Obj
{
static
{
Obj init(Outbuffer *, const(char)* filename, const(char)* csegname);
void initfile(const(char)* filename, const(char)* csegname, const(char)* modname);
void termfile();
void term(const(char)* objfilename);
size_t mangle(Symbol *s,char *dest);
void _import(elem *e);
void linnum(Srcpos srcpos, int seg, targ_size_t offset);
int codeseg(char *name,int suffix);
void dosseg();
void startaddress(Symbol *);
bool includelib(const(char)* );
bool allowZeroSize();
void exestr(const(char)* p);
void user(const(char)* p);
void compiler();
void wkext(Symbol *,Symbol *);
void lzext(Symbol *,Symbol *);
void _alias(const(char)* n1,const(char)* n2);
void theadr(const(char)* modname);
void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
void staticctor(Symbol *s,int dtor,int seg);
void staticdtor(Symbol *s);
void setModuleCtorDtor(Symbol *s, bool isCtor);
void ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym);
void ehsections();
void moduleinfo(Symbol *scc);
}
final int comdat(Symbol *);
final int comdatsize(Symbol *, targ_size_t symsize);
final int readonly_comdat(Symbol *s);
static
{
void setcodeseg(int seg);
seg_data *tlsseg();
seg_data *tlsseg_bss();
seg_data *tlsseg_data();
int fardata(char *name, targ_size_t size, targ_size_t *poffset);
void export_symbol(Symbol *s, uint argsize);
void pubdef(int seg, Symbol *s, targ_size_t offset);
void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
int external_def(const(char)* );
int data_start(Symbol *sdata, targ_size_t datasize, int seg);
int external(Symbol *);
int common_block(Symbol *s, targ_size_t size, targ_size_t count);
int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
void lidata(int seg, targ_size_t offset, targ_size_t count);
void write_zeros(seg_data *pseg, targ_size_t count);
void write_byte(seg_data *pseg, uint _byte);
void write_bytes(seg_data *pseg, uint nbytes, void *p);
void _byte(int seg, targ_size_t offset, uint _byte);
uint bytes(int seg, targ_size_t offset, uint nbytes, void *p);
void ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2);
void write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2);
void reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags);
void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
void reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
void far16thunk(Symbol *s);
void fltused();
int data_readonly(char *p, int len, int *pseg);
int data_readonly(char *p, int len);
int string_literal_segment(uint sz);
Symbol *sym_cdata(tym_t, char *, int);
void func_start(Symbol *sfunc);
void func_term(Symbol *sfunc);
void write_pointerRef(Symbol* s, uint off);
int jmpTableSegment(Symbol* s);
Symbol *tlv_bootstrap();
void gotref(Symbol *s);
int seg_debugT(); // where the symbolic debug type data goes
}
}
}
else version (OMFandMSCOFF)
{
class Obj
{
public:
static Obj init(Outbuffer *, const(char)* filename, const(char)* csegname);
void initfile(const(char)* filename, const(char)* csegname, const(char)* modname);
void termfile();
void term(const(char)* objfilename);
size_t mangle(Symbol *s,char *dest);
void _import(elem *e);
void linnum(Srcpos srcpos, int seg, targ_size_t offset);
int codeseg(char *name,int suffix);
void dosseg();
void startaddress(Symbol *);
bool includelib(const(char)* );
bool allowZeroSize();
void exestr(const(char)* p);
void user(const(char)* p);
void compiler();
void wkext(Symbol *,Symbol *);
void lzext(Symbol *,Symbol *);
void _alias(const(char)* n1,const(char)* n2);
void theadr(const(char)* modname);
void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
void staticctor(Symbol *s,int dtor,int seg);
void staticdtor(Symbol *s);
void setModuleCtorDtor(Symbol *s, bool isCtor);
void ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym);
void ehsections();
void moduleinfo(Symbol *scc);
int comdat(Symbol *);
int comdatsize(Symbol *, targ_size_t symsize);
int readonly_comdat(Symbol *s);
void setcodeseg(int seg);
seg_data *tlsseg();
seg_data *tlsseg_bss();
seg_data *tlsseg_data();
static int fardata(char *name, targ_size_t size, targ_size_t *poffset);
void export_symbol(Symbol *s, uint argsize);
void pubdef(int seg, Symbol *s, targ_size_t offset);
void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
int external_def(const(char)* );
int data_start(Symbol *sdata, targ_size_t datasize, int seg);
int external(Symbol *);
int common_block(Symbol *s, targ_size_t size, targ_size_t count);
int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
void lidata(int seg, targ_size_t offset, targ_size_t count);
void write_zeros(seg_data *pseg, targ_size_t count);
void write_byte(seg_data *pseg, uint _byte);
void write_bytes(seg_data *pseg, uint nbytes, void *p);
void _byte(int seg, targ_size_t offset, uint _byte);
uint bytes(int seg, targ_size_t offset, uint nbytes, void *p);
void ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2);
void write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2);
void reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags);
void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
void reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
void far16thunk(Symbol *s);
void fltused();
int data_readonly(char *p, int len, int *pseg);
int data_readonly(char *p, int len);
int string_literal_segment(uint sz);
Symbol *sym_cdata(tym_t, char *, int);
void func_start(Symbol *sfunc);
void func_term(Symbol *sfunc);
void write_pointerRef(Symbol* s, uint off);
int jmpTableSegment(Symbol* s);
Symbol *tlv_bootstrap();
static void gotref(Symbol *s);
int seg_debugT(); // where the symbolic debug type data goes
}
class MsCoffObj : Obj
{
public:
static MsCoffObj init(Outbuffer *, const(char)* filename, const(char)* csegname);
override void initfile(const(char)* filename, const(char)* csegname, const(char)* modname);
override void termfile();
override void term(const(char)* objfilename);
override void compiler();
override void exestr(const(char)* p);
//override void dosseg();
//override size_t mangle(Symbol *s,char *dest);
override void startaddress(Symbol *);
override bool includelib(const(char)* );
override void _alias(const(char)* n1,const(char)* n2);
override void user(const(char)* p);
// void _import(elem *e);
override void linnum(Srcpos srcpos, int seg, targ_size_t offset);
override int codeseg(char *name,int suffix);
override bool allowZeroSize();
override void wkext(Symbol *,Symbol *);
// void lzext(Symbol *,Symbol *);
// void theadr(const(char)* modname);
// void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
override void staticctor(Symbol *s,int dtor,int seg);
override void staticdtor(Symbol *s);
override void setModuleCtorDtor(Symbol *s, bool isCtor);
override void ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym);
override void ehsections();
override void moduleinfo(Symbol *scc);
override int comdat(Symbol *);
override int comdatsize(Symbol *, targ_size_t symsize);
override int readonly_comdat(Symbol *s);
override void setcodeseg(int seg);
override seg_data *tlsseg();
override seg_data *tlsseg_bss();
override seg_data *tlsseg_data();
override void export_symbol(Symbol *s, uint argsize);
override void pubdef(int seg, Symbol *s, targ_size_t offset);
override void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
// int external(const(char)* );
override int external_def(const(char)* );
override int data_start(Symbol *sdata, targ_size_t datasize, int seg);
override int external(Symbol *);
override int common_block(Symbol *s, targ_size_t size, targ_size_t count);
override int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
override void lidata(int seg, targ_size_t offset, targ_size_t count);
override void write_zeros(seg_data *pseg, targ_size_t count);
override void write_byte(seg_data *pseg, uint _byte);
override void write_bytes(seg_data *pseg, uint nbytes, void *p);
override void _byte(int seg, targ_size_t offset, uint _byte);
override uint bytes(int seg, targ_size_t offset, uint nbytes, void *p);
// void ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2);
// void write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2);
override void reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags);
// void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
override void reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
override int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
override void far16thunk(Symbol *s);
override void fltused();
override int data_readonly(char *p, int len, int *pseg);
override int data_readonly(char *p, int len);
override int string_literal_segment(uint sz);
override Symbol *sym_cdata(tym_t, char *, int);
static uint addstr(Outbuffer *strtab, const(char)* );
static void func_start(Symbol *sfunc);
static void func_term(Symbol *sfunc);
override void write_pointerRef(Symbol* s, uint off);
override int jmpTableSegment(Symbol* s);
static int getsegment(const(char)* sectname, uint flags);
static int getsegment2( uint shtidx);
static uint addScnhdr(const(char)* scnhdr_name, uint flags);
static void addrel(int seg, targ_size_t offset, Symbol *targsym,
uint targseg, int rtype, int val);
// static void addrel(int seg, targ_size_t offset, uint type,
// uint symidx, targ_size_t val);
static int seg_pdata();
static int seg_xdata();
static int seg_pdata_comdat(Symbol *sfunc);
static int seg_xdata_comdat(Symbol *sfunc);
static int seg_debugS();
override int seg_debugT();
static int seg_debugS_comdat(Symbol *sfunc);
override Symbol *tlv_bootstrap();
}
}
else version (Posix)
{
class Obj
{
public:
static Obj init(Outbuffer *, const(char)* filename, const(char)* csegname);
static void initfile(const(char)* filename, const(char)* csegname, const(char)* modname);
static void termfile();
static void term(const(char)* objfilename);
static void compiler();
static void exestr(const(char)* p);
static void dosseg();
static void startaddress(Symbol *);
static bool includelib(const(char)* );
static size_t mangle(Symbol *s,char *dest);
static void _alias(const(char)* n1,const(char)* n2);
static void user(const(char)* p);
static void _import(elem *e);
static void linnum(Srcpos srcpos, int seg, targ_size_t offset);
static int codeseg(char *name,int suffix);
static bool allowZeroSize();
static void wkext(Symbol *,Symbol *);
static void lzext(Symbol *,Symbol *);
static void theadr(const(char)* modname);
static void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
static void staticctor(Symbol *s,int dtor,int seg);
static void staticdtor(Symbol *s);
static void setModuleCtorDtor(Symbol *s, bool isCtor);
static void ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym);
static void ehsections();
static void moduleinfo(Symbol *scc);
int comdat(Symbol *);
static int comdatsize(Symbol *, targ_size_t symsize);
int readonly_comdat(Symbol *s);
static void setcodeseg(int seg);
seg_data *tlsseg();
seg_data *tlsseg_bss();
static seg_data *tlsseg_data();
static int fardata(char *name, targ_size_t size, targ_size_t *poffset);
static void export_symbol(Symbol *s, uint argsize);
static void pubdef(int seg, Symbol *s, targ_size_t offset);
static void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
static int external_def(const(char)* );
static int data_start(Symbol *sdata, targ_size_t datasize, int seg);
static int external(Symbol *);
static int common_block(Symbol *s, targ_size_t size, targ_size_t count);
static int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
static void lidata(int seg, targ_size_t offset, targ_size_t count);
static void write_zeros(seg_data *pseg, targ_size_t count);
static void write_byte(seg_data *pseg, uint _byte);
static void write_bytes(seg_data *pseg, uint nbytes, void *p);
static void _byte(int seg, targ_size_t offset, uint _byte);
static uint bytes(int seg, targ_size_t offset, uint nbytes, void *p);
static void ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2);
static void write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2);
static void reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags);
static void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
static void reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
static int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
static void far16thunk(Symbol *s);
static void fltused();
static int data_readonly(char *p, int len, int *pseg);
static int data_readonly(char *p, int len);
static int string_literal_segment(uint sz);
static Symbol *sym_cdata(tym_t, char *, int);
static void func_start(Symbol *sfunc);
static void func_term(Symbol *sfunc);
static void write_pointerRef(Symbol* s, uint off);
static int jmpTableSegment(Symbol* s);
static Symbol *tlv_bootstrap();
static void gotref(Symbol *s);
static uint addstr(Outbuffer *strtab, const(char)* );
static Symbol *getGOTsym();
static void refGOTsym();
}
version (OSX)
{
class MachObj : Obj
{
public:
static int getsegment(const(char)* sectname, const(char)* segname,
int _align, int flags);
static void addrel(int seg, targ_size_t offset, Symbol *targsym,
uint targseg, int rtype, int val = 0);
}
class MachObj64 : MachObj
{
public:
override seg_data *tlsseg();
override seg_data *tlsseg_bss();
}
}
else
{
class ElfObj : Obj
{
public:
static int getsegment(const(char)* name, const(char)* suffix,
int type, int flags, int _align);
static void addrel(int seg, targ_size_t offset, uint type,
uint symidx, targ_size_t val);
static size_t writerel(int targseg, size_t offset, uint type,
uint symidx, targ_size_t val);
}
}
}
else version (STUB)
{
public import stubobj;
}
else
static assert(0, "unsupported version");
extern __gshared Obj objmod;