dmd/src/ddmd/backend/obj.h

337 lines
14 KiB
C++

/**
* Compiler implementation of the
* $(LINK2 http://www.dlang.org, D programming language).
*
* Copyright: Copyright (c) 2012-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)
*/
/* Interface to object file format
*/
//#pragma once
#ifndef OBJ_H
#define OBJ_H 1
struct seg_data;
#if MARS && TARGET_WINDOS && !HTOD
#define OMFandMSCOFF 1
#define VIRTUAL virtual
#else
#if TARGET_WINDOS
#define OMF 1
#elif (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS)
#define ELF 1
#elif TARGET_OSX
#define MACH 1
#endif
#define VIRTUAL static
#endif
#if OMF
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 size_t mangle(Symbol *s,char *dest);
static void _import(elem *e);
static void linnum(Srcpos srcpos, int seg, targ_size_t offset);
static int codeseg(char *name,int suffix);
static void dosseg(void);
static void startaddress(Symbol *);
static bool includelib(const char *);
static bool allowZeroSize();
static void exestr(const char *p);
static void user(const char *p);
static void compiler();
static void wkext(Symbol *,Symbol *);
static void lzext(Symbol *,Symbol *);
static void _alias(const char *n1,const char *n2);
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 *);
int comdatsize(Symbol *, targ_size_t symsize);
int readonly_comdat(Symbol *s);
static void setcodeseg(int seg);
static seg_data *tlsseg();
static 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, unsigned 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, unsigned byte);
static void write_bytes(seg_data *pseg, unsigned nbytes, void *p);
static void _byte(int seg, targ_size_t offset, unsigned byte);
static unsigned bytes(int seg, targ_size_t offset, unsigned nbytes, void *p);
static void ledata(int seg, targ_size_t offset, targ_size_t data, unsigned lcfd, unsigned idx1, unsigned idx2);
static void write_long(int seg, targ_size_t offset, unsigned data, unsigned lcfd, unsigned idx1, unsigned idx2);
static void reftodatseg(int seg, targ_size_t offset, targ_size_t val, unsigned 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(unsigned 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, unsigned off);
static int jmpTableSegment(Symbol* s);
static symbol *tlv_bootstrap();
static void gotref(symbol *s);
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
static unsigned addstr(Outbuffer *strtab, const char *);
static symbol *getGOTsym();
static void refGOTsym();
#endif
#if TARGET_WINDOS
static int seg_debugT(); // where the symbolic debug type data goes
#endif
};
#else
class Obj
{
public:
static Obj *init(Outbuffer *, const char *filename, const char *csegname);
VIRTUAL void initfile(const char *filename, const char *csegname, const char *modname);
VIRTUAL void termfile();
VIRTUAL void term(const char *objfilename);
VIRTUAL size_t mangle(Symbol *s,char *dest);
VIRTUAL void _import(elem *e);
VIRTUAL void linnum(Srcpos srcpos, int seg, targ_size_t offset);
VIRTUAL int codeseg(char *name,int suffix);
VIRTUAL void dosseg(void);
VIRTUAL void startaddress(Symbol *);
VIRTUAL bool includelib(const char *);
VIRTUAL bool allowZeroSize();
VIRTUAL void exestr(const char *p);
VIRTUAL void user(const char *p);
VIRTUAL void compiler();
VIRTUAL void wkext(Symbol *,Symbol *);
VIRTUAL void lzext(Symbol *,Symbol *);
VIRTUAL void _alias(const char *n1,const char *n2);
VIRTUAL void theadr(const char *modname);
VIRTUAL void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
VIRTUAL void staticctor(Symbol *s,int dtor,int seg);
VIRTUAL void staticdtor(Symbol *s);
VIRTUAL void setModuleCtorDtor(Symbol *s, bool isCtor);
VIRTUAL void ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym);
VIRTUAL void ehsections();
VIRTUAL void moduleinfo(Symbol *scc);
virtual int comdat(Symbol *);
virtual int comdatsize(Symbol *, targ_size_t symsize);
virtual int readonly_comdat(Symbol *s);
VIRTUAL void setcodeseg(int seg);
virtual seg_data *tlsseg();
virtual seg_data *tlsseg_bss();
VIRTUAL seg_data *tlsseg_data();
static int fardata(char *name, targ_size_t size, targ_size_t *poffset);
VIRTUAL void export_symbol(Symbol *s, unsigned argsize);
VIRTUAL void pubdef(int seg, Symbol *s, targ_size_t offset);
VIRTUAL void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
VIRTUAL int external_def(const char *);
VIRTUAL int data_start(Symbol *sdata, targ_size_t datasize, int seg);
VIRTUAL int external(Symbol *);
VIRTUAL int common_block(Symbol *s, targ_size_t size, targ_size_t count);
VIRTUAL int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
VIRTUAL void lidata(int seg, targ_size_t offset, targ_size_t count);
VIRTUAL void write_zeros(seg_data *pseg, targ_size_t count);
VIRTUAL void write_byte(seg_data *pseg, unsigned byte);
VIRTUAL void write_bytes(seg_data *pseg, unsigned nbytes, void *p);
VIRTUAL void _byte(int seg, targ_size_t offset, unsigned byte);
VIRTUAL unsigned bytes(int seg, targ_size_t offset, unsigned nbytes, void *p);
VIRTUAL void ledata(int seg, targ_size_t offset, targ_size_t data, unsigned lcfd, unsigned idx1, unsigned idx2);
VIRTUAL void write_long(int seg, targ_size_t offset, unsigned data, unsigned lcfd, unsigned idx1, unsigned idx2);
VIRTUAL void reftodatseg(int seg, targ_size_t offset, targ_size_t val, unsigned targetdatum, int flags);
VIRTUAL void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
VIRTUAL void reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
VIRTUAL int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
VIRTUAL void far16thunk(Symbol *s);
VIRTUAL void fltused();
VIRTUAL int data_readonly(char *p, int len, int *pseg);
VIRTUAL int data_readonly(char *p, int len);
VIRTUAL int string_literal_segment(unsigned sz);
VIRTUAL symbol *sym_cdata(tym_t, char *, int);
VIRTUAL void func_start(Symbol *sfunc);
VIRTUAL void func_term(Symbol *sfunc);
VIRTUAL void write_pointerRef(Symbol* s, unsigned off);
VIRTUAL int jmpTableSegment(Symbol* s);
VIRTUAL symbol *tlv_bootstrap();
static void gotref(symbol *s);
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
static unsigned addstr(Outbuffer *strtab, const char *);
static symbol *getGOTsym();
static void refGOTsym();
#endif
#if TARGET_WINDOS
VIRTUAL int seg_debugT(); // where the symbolic debug type data goes
#endif
};
class ElfObj : public 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, unsigned type,
unsigned symidx, targ_size_t val);
static size_t writerel(int targseg, size_t offset, unsigned type,
unsigned symidx, targ_size_t val);
};
class MachObj : public 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,
unsigned targseg, int rtype, int val = 0);
};
class MachObj64 : public MachObj
{
public:
seg_data *tlsseg();
seg_data *tlsseg_bss();
};
class MsCoffObj : public Obj
{
public:
static MsCoffObj *init(Outbuffer *, const char *filename, const char *csegname);
VIRTUAL void initfile(const char *filename, const char *csegname, const char *modname);
VIRTUAL void termfile();
VIRTUAL void term(const char *objfilename);
// VIRTUAL size_t mangle(Symbol *s,char *dest);
// VIRTUAL void _import(elem *e);
VIRTUAL void linnum(Srcpos srcpos, int seg, targ_size_t offset);
VIRTUAL int codeseg(char *name,int suffix);
// VIRTUAL void dosseg(void);
VIRTUAL void startaddress(Symbol *);
VIRTUAL bool includelib(const char *);
VIRTUAL bool allowZeroSize();
VIRTUAL void exestr(const char *p);
VIRTUAL void user(const char *p);
VIRTUAL void compiler();
VIRTUAL void wkext(Symbol *,Symbol *);
// VIRTUAL void lzext(Symbol *,Symbol *);
VIRTUAL void _alias(const char *n1,const char *n2);
// VIRTUAL void theadr(const char *modname);
// VIRTUAL void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
VIRTUAL void staticctor(Symbol *s,int dtor,int seg);
VIRTUAL void staticdtor(Symbol *s);
VIRTUAL void setModuleCtorDtor(Symbol *s, bool isCtor);
VIRTUAL void ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym);
VIRTUAL void ehsections();
VIRTUAL void moduleinfo(Symbol *scc);
virtual int comdat(Symbol *);
virtual int comdatsize(Symbol *, targ_size_t symsize);
virtual int readonly_comdat(Symbol *s);
VIRTUAL void setcodeseg(int seg);
virtual seg_data *tlsseg();
virtual seg_data *tlsseg_bss();
virtual seg_data *tlsseg_data();
VIRTUAL void export_symbol(Symbol *s, unsigned argsize);
VIRTUAL void pubdef(int seg, Symbol *s, targ_size_t offset);
VIRTUAL void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
// VIRTUAL int external(const char *);
VIRTUAL int external_def(const char *);
VIRTUAL int data_start(Symbol *sdata, targ_size_t datasize, int seg);
VIRTUAL int external(Symbol *);
VIRTUAL int common_block(Symbol *s, targ_size_t size, targ_size_t count);
VIRTUAL int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
VIRTUAL void lidata(int seg, targ_size_t offset, targ_size_t count);
VIRTUAL void write_zeros(seg_data *pseg, targ_size_t count);
VIRTUAL void write_byte(seg_data *pseg, unsigned byte);
VIRTUAL void write_bytes(seg_data *pseg, unsigned nbytes, void *p);
VIRTUAL void _byte(int seg, targ_size_t offset, unsigned byte);
VIRTUAL unsigned bytes(int seg, targ_size_t offset, unsigned nbytes, void *p);
// VIRTUAL void ledata(int seg, targ_size_t offset, targ_size_t data, unsigned lcfd, unsigned idx1, unsigned idx2);
// VIRTUAL void write_long(int seg, targ_size_t offset, unsigned data, unsigned lcfd, unsigned idx1, unsigned idx2);
VIRTUAL void reftodatseg(int seg, targ_size_t offset, targ_size_t val, unsigned targetdatum, int flags);
// VIRTUAL void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
VIRTUAL void reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
VIRTUAL int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
VIRTUAL void far16thunk(Symbol *s);
VIRTUAL void fltused();
VIRTUAL int data_readonly(char *p, int len, int *pseg);
VIRTUAL int data_readonly(char *p, int len);
VIRTUAL int string_literal_segment(unsigned sz);
VIRTUAL symbol *sym_cdata(tym_t, char *, int);
static unsigned addstr(Outbuffer *strtab, const char *);
VIRTUAL void func_start(Symbol *sfunc);
VIRTUAL void func_term(Symbol *sfunc);
VIRTUAL void write_pointerRef(Symbol* s, unsigned off);
VIRTUAL int jmpTableSegment(Symbol* s);
static int getsegment(const char *sectname, unsigned long flags);
static int getsegment2(unsigned shtidx);
static unsigned addScnhdr(const char *scnhdr_name, unsigned long flags);
static void addrel(int seg, targ_size_t offset, symbol *targsym,
unsigned targseg, int rtype, int val);
// static void addrel(int seg, targ_size_t offset, unsigned type,
// unsigned symidx, targ_size_t val);
static int seg_drectve();
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();
VIRTUAL int seg_debugT();
static int seg_debugS_comdat(Symbol *sfunc);
VIRTUAL symbol *tlv_bootstrap();
};
#endif
extern Obj *objmod;
#undef OMF
#undef OMFandMSCOFF
#undef ELF
#undef MACH
#undef VIRTUAL
#endif