1 /**
2  * Compiler implementation of the
3  * $(LINK2 http://www.dlang.org, D programming language).
4  *
5  * Copyright:   Copyright (C) 1994-1998 by Symantec
6  *              Copyright (C) 2000-2020 by The D Language Foundation, All Rights Reserved
7  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
8  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/obj.d, backend/obj.d)
10  */
11 
12 module dmd.backend.obj;
13 
14 // Online documentation: https://dlang.org/phobos/dmd_backend_obj.html
15 
16 /* Interface to object file format
17  */
18 
19 import dmd.backend.cdef;
20 import dmd.backend.cc;
21 import dmd.backend.code;
22 import dmd.backend.el;
23 import dmd.backend.outbuf;
24 
25 extern (C++):
26 
27 nothrow:
28 
29 version (SPP)
30     version = STUB;
31 else version (HTOD)
32     version = STUB;
33 else version (Windows)
34     version = OMFandMSCOFF;
35 else version (Posix)
36     version = ELFandMACH;
37 else
38     static assert(0, "unsupported version");
39 
40 
41 version (Windows)
42 {
43     Obj  OmfObj_init(Outbuffer *, const(char)* filename, const(char)* csegname);
44     void OmfObj_initfile(const(char)* filename, const(char)* csegname, const(char)* modname);
45     void OmfObj_termfile();
46     void OmfObj_term(const(char)* objfilename);
47     size_t OmfObj_mangle(Symbol *s,char *dest);
48     void OmfObj_import(elem *e);
49     void OmfObj_linnum(Srcpos srcpos, int seg, targ_size_t offset);
50     int  OmfObj_codeseg(const char *name,int suffix);
51     void OmfObj_dosseg();
52     void OmfObj_startaddress(Symbol *);
53     bool OmfObj_includelib(const(char)* );
54     bool OmfObj_linkerdirective(const(char)* );
55     bool OmfObj_allowZeroSize();
56     void OmfObj_exestr(const(char)* p);
57     void OmfObj_user(const(char)* p);
58     void OmfObj_compiler();
59     void OmfObj_wkext(Symbol *,Symbol *);
60     void OmfObj_lzext(Symbol *,Symbol *);
61     void OmfObj_alias(const(char)* n1,const(char)* n2);
62     void OmfObj_theadr(const(char)* modname);
63     void OmfObj_segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
64     void OmfObj_staticctor(Symbol *s,int dtor,int seg);
65     void OmfObj_staticdtor(Symbol *s);
66     void OmfObj_setModuleCtorDtor(Symbol *s, bool isCtor);
67     void OmfObj_ehtables(Symbol *sfunc,uint size,Symbol *ehsym);
68     void OmfObj_ehsections();
69     void OmfObj_moduleinfo(Symbol *scc);
70     int  OmfObj_comdat(Symbol *);
71     int  OmfObj_comdatsize(Symbol *, targ_size_t symsize);
72     int  OmfObj_readonly_comdat(Symbol *s);
73     void OmfObj_setcodeseg(int seg);
74     seg_data* OmfObj_tlsseg();
75     seg_data* OmfObj_tlsseg_bss();
76     seg_data* OmfObj_tlsseg_data();
77     int  OmfObj_fardata(char *name, targ_size_t size, targ_size_t *poffset);
78     void OmfObj_export_symbol(Symbol *s, uint argsize);
79     void OmfObj_pubdef(int seg, Symbol *s, targ_size_t offset);
80     void OmfObj_pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
81     int  OmfObj_external_def(const(char)* );
82     int  OmfObj_data_start(Symbol *sdata, targ_size_t datasize, int seg);
83     int  OmfObj_external(Symbol *);
84     int  OmfObj_common_block(Symbol *s, targ_size_t size, targ_size_t count);
85     int  OmfObj_common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
86     void OmfObj_lidata(int seg, targ_size_t offset, targ_size_t count);
87     void OmfObj_write_zeros(seg_data *pseg, targ_size_t count);
88     void OmfObj_write_byte(seg_data *pseg, uint _byte);
89     void OmfObj_write_bytes(seg_data *pseg, uint nbytes, void *p);
90     void OmfObj_byte(int seg, targ_size_t offset, uint _byte);
91     uint OmfObj_bytes(int seg, targ_size_t offset, uint nbytes, void *p);
92     void OmfObj_ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2);
93     void OmfObj_write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2);
94     void OmfObj_reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags);
95     void OmfObj_reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
96     void OmfObj_reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
97     int  OmfObj_reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
98     void OmfObj_far16thunk(Symbol *s);
99     void OmfObj_fltused();
100     int  OmfObj_data_readonly(char *p, int len, int *pseg);
101     int  OmfObj_data_readonly(char *p, int len);
102     int  OmfObj_string_literal_segment(uint sz);
103     Symbol* OmfObj_sym_cdata(tym_t, char *, int);
104     void OmfObj_func_start(Symbol *sfunc);
105     void OmfObj_func_term(Symbol *sfunc);
106     void OmfObj_write_pointerRef(Symbol* s, uint off);
107     int  OmfObj_jmpTableSegment(Symbol* s);
108     Symbol* OmfObj_tlv_bootstrap();
109     void OmfObj_gotref(Symbol *s);
110     int  OmfObj_seg_debugT();           // where the symbolic debug type data goes
111 
112     Obj  MsCoffObj_init(Outbuffer *, const(char)* filename, const(char)* csegname);
113     void MsCoffObj_initfile(const(char)* filename, const(char)* csegname, const(char)* modname);
114     void MsCoffObj_termfile();
115     void MsCoffObj_term(const(char)* objfilename);
116 //    size_t MsCoffObj_mangle(Symbol *s,char *dest);
117 //    void MsCoffObj_import(elem *e);
118     void MsCoffObj_linnum(Srcpos srcpos, int seg, targ_size_t offset);
119     int  MsCoffObj_codeseg(const char *name,int suffix);
120 //    void MsCoffObj_dosseg();
121     void MsCoffObj_startaddress(Symbol *);
122     bool MsCoffObj_includelib(const(char)* );
123     bool MsCoffObj_linkerdirective(const(char)* );
124     bool MsCoffObj_allowZeroSize();
125     void MsCoffObj_exestr(const(char)* p);
126     void MsCoffObj_user(const(char)* p);
127     void MsCoffObj_compiler();
128     void MsCoffObj_wkext(Symbol *,Symbol *);
129 //    void MsCoffObj_lzext(Symbol *,Symbol *);
130     void MsCoffObj_alias(const(char)* n1,const(char)* n2);
131 //    void MsCoffObj_theadr(const(char)* modname);
132 //    void MsCoffObj_segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
133     void MsCoffObj_staticctor(Symbol *s,int dtor,int seg);
134     void MsCoffObj_staticdtor(Symbol *s);
135     void MsCoffObj_setModuleCtorDtor(Symbol *s, bool isCtor);
136     void MsCoffObj_ehtables(Symbol *sfunc,uint size,Symbol *ehsym);
137     void MsCoffObj_ehsections();
138     void MsCoffObj_moduleinfo(Symbol *scc);
139     int  MsCoffObj_comdat(Symbol *);
140     int  MsCoffObj_comdatsize(Symbol *, targ_size_t symsize);
141     int  MsCoffObj_readonly_comdat(Symbol *s);
142     void MsCoffObj_setcodeseg(int seg);
143     seg_data* MsCoffObj_tlsseg();
144     seg_data* MsCoffObj_tlsseg_bss();
145     seg_data* MsCoffObj_tlsseg_data();
146 //    int  MsCoffObj_fardata(char *name, targ_size_t size, targ_size_t *poffset);
147     void MsCoffObj_export_symbol(Symbol *s, uint argsize);
148     void MsCoffObj_pubdef(int seg, Symbol *s, targ_size_t offset);
149     void MsCoffObj_pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
150     int  MsCoffObj_external_def(const(char)* );
151     int  MsCoffObj_data_start(Symbol *sdata, targ_size_t datasize, int seg);
152     int  MsCoffObj_external(Symbol *);
153     int  MsCoffObj_common_block(Symbol *s, targ_size_t size, targ_size_t count);
154     int  MsCoffObj_common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
155     void MsCoffObj_lidata(int seg, targ_size_t offset, targ_size_t count);
156     void MsCoffObj_write_zeros(seg_data *pseg, targ_size_t count);
157     void MsCoffObj_write_byte(seg_data *pseg, uint _byte);
158     void MsCoffObj_write_bytes(seg_data *pseg, uint nbytes, void *p);
159     void MsCoffObj_byte(int seg, targ_size_t offset, uint _byte);
160     uint MsCoffObj_bytes(int seg, targ_size_t offset, uint nbytes, void *p);
161 //    void MsCoffObj_ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2);
162 //    void MsCoffObj_write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2);
163     void MsCoffObj_reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags);
164 //    void MsCoffObj_reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
165     void MsCoffObj_reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
166     int  MsCoffObj_reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
167     void MsCoffObj_far16thunk(Symbol *s);
168     void MsCoffObj_fltused();
169     int  MsCoffObj_data_readonly(char *p, int len, int *pseg);
170     int  MsCoffObj_data_readonly(char *p, int len);
171     int  MsCoffObj_string_literal_segment(uint sz);
172     Symbol* MsCoffObj_sym_cdata(tym_t, char *, int);
173     void MsCoffObj_func_start(Symbol *sfunc);
174     void MsCoffObj_func_term(Symbol *sfunc);
175     void MsCoffObj_write_pointerRef(Symbol* s, uint off);
176     int  MsCoffObj_jmpTableSegment(Symbol* s);
177     Symbol* MsCoffObj_tlv_bootstrap();
178 //    void MsCoffObj_gotref(Symbol *s);
179     int  MsCoffObj_seg_debugT();           // where the symbolic debug type data goes
180 
181     int  MsCoffObj_getsegment(const(char)* sectname, uint flags);
182     int  MsCoffObj_getsegment2( uint shtidx);
183     uint MsCoffObj_addScnhdr(const(char)* scnhdr_name, uint flags);
184     void MsCoffObj_addrel(int seg, targ_size_t offset, Symbol *targsym,
185                           uint targseg, int rtype, int val);
186     int  MsCoffObj_seg_drectve();
187     int  MsCoffObj_seg_pdata();
188     int  MsCoffObj_seg_xdata();
189     int  MsCoffObj_seg_pdata_comdat(Symbol *sfunc);
190     int  MsCoffObj_seg_xdata_comdat(Symbol *sfunc);
191     int  MsCoffObj_seg_debugS();
192     int  MsCoffObj_seg_debugS_comdat(Symbol *sfunc);
193 }
194 
195 version (Posix)
196 {
197     Obj Obj_init(Outbuffer *, const(char)* filename, const(char)* csegname);
198     void Obj_initfile(const(char)* filename, const(char)* csegname, const(char)* modname);
199     void Obj_termfile();
200     void Obj_term(const(char)* objfilename);
201     void Obj_compiler();
202     void Obj_exestr(const(char)* p);
203     void Obj_dosseg();
204     void Obj_startaddress(Symbol *);
205     bool Obj_includelib(const(char)* );
206     bool Obj_linkerdirective(const(char)* p);
207     size_t Obj_mangle(Symbol *s,char *dest);
208     void Obj_alias(const(char)* n1,const(char)* n2);
209     void Obj_user(const(char)* p);
210 
211     void Obj_import(elem *e);
212     void Obj_linnum(Srcpos srcpos, int seg, targ_size_t offset);
213     int Obj_codeseg(const char *name,int suffix);
214     bool Obj_allowZeroSize();
215     void Obj_wkext(Symbol *,Symbol *);
216     void Obj_lzext(Symbol *,Symbol *);
217     void Obj_theadr(const(char)* modname);
218     void Obj_segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize);
219     void Obj_staticctor(Symbol *s,int dtor,int seg);
220     void Obj_staticdtor(Symbol *s);
221     void Obj_setModuleCtorDtor(Symbol *s, bool isCtor);
222     void Obj_ehtables(Symbol *sfunc,uint size,Symbol *ehsym);
223     void Obj_ehsections();
224     void Obj_moduleinfo(Symbol *scc);
225     int Obj_comdat(Symbol *);
226     int Obj_comdatsize(Symbol *, targ_size_t symsize);
227     int Obj_readonly_comdat(Symbol *s);
228     void Obj_setcodeseg(int seg);
229     seg_data* Obj_tlsseg();
230     seg_data* Obj_tlsseg_bss();
231     seg_data* Obj_tlsseg_data();
232     int Obj_fardata(char *name, targ_size_t size, targ_size_t *poffset);
233     void Obj_export_symbol(Symbol *s, uint argsize);
234     void Obj_pubdef(int seg, Symbol *s, targ_size_t offset);
235     void Obj_pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize);
236     int Obj_external_def(const(char)* );
237     int Obj_data_start(Symbol *sdata, targ_size_t datasize, int seg);
238     int Obj_external(Symbol *);
239     int Obj_common_block(Symbol *s, targ_size_t size, targ_size_t count);
240     int Obj_common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count);
241     void Obj_lidata(int seg, targ_size_t offset, targ_size_t count);
242     void Obj_write_zeros(seg_data *pseg, targ_size_t count);
243     void Obj_write_byte(seg_data *pseg, uint _byte);
244     void Obj_write_bytes(seg_data *pseg, uint nbytes, void *p);
245     void Obj_byte(int seg, targ_size_t offset, uint _byte);
246     uint Obj_bytes(int seg, targ_size_t offset, uint nbytes, void *p);
247     void Obj_ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2);
248     void Obj_write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2);
249     void Obj_reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags);
250     void Obj_reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags);
251     void Obj_reftocodeseg(int seg, targ_size_t offset, targ_size_t val);
252     int Obj_reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags);
253     void Obj_far16thunk(Symbol *s);
254     void Obj_fltused();
255     int Obj_data_readonly(char *p, int len, int *pseg);
256     int Obj_data_readonly(char *p, int len);
257     int Obj_string_literal_segment(uint sz);
258     Symbol* Obj_sym_cdata(tym_t, char *, int);
259     void Obj_func_start(Symbol *sfunc);
260     void Obj_func_term(Symbol *sfunc);
261     void Obj_write_pointerRef(Symbol* s, uint off);
262     int Obj_jmpTableSegment(Symbol* s);
263 
264     Symbol* Obj_tlv_bootstrap();
265 
266     void Obj_gotref(Symbol *s);
267 
268     uint Obj_addstr(Outbuffer *strtab, const(char)* );
269     Symbol* Obj_getGOTsym();
270     void Obj_refGOTsym();
271 
272     version (OSX)
273     {
274         int Obj_getsegment(const(char)* sectname, const(char)* segname,
275                               int  _align, int flags);
276         void Obj_addrel(int seg, targ_size_t offset, Symbol *targsym,
277                            uint targseg, int rtype, int val = 0);
278     }
279     else
280     {
281         int Obj_getsegment(const(char)* name, const(char)* suffix,
282                               int type, int flags, int  _align);
283         void Obj_addrel(int seg, targ_size_t offset, uint type,
284                            uint symidx, targ_size_t val);
285         size_t Obj_writerel(int targseg, size_t offset, uint type,
286                                uint symidx, targ_size_t val);
287     }
288 }
289 
290 version (OMFandMSCOFF)
291 {
292     class Obj
293     {
294       static
295       {
296         nothrow:
297 
298         Obj init(Outbuffer* objbuf, const(char)* filename, const(char)* csegname)
299         {
300             return config.objfmt == OBJ_MSCOFF
301                 ? MsCoffObj_init(objbuf, filename, csegname)
302                 :    OmfObj_init(objbuf, filename, csegname);
303         }
304 
305         void initfile(const(char)* filename, const(char)* csegname, const(char)* modname)
306         {
307             return config.objfmt == OBJ_MSCOFF
308                 ? MsCoffObj_initfile(filename, csegname, modname)
309                 :    OmfObj_initfile(filename, csegname, modname);
310         }
311 
312         void termfile()
313         {
314             return config.objfmt == OBJ_MSCOFF
315                 ? MsCoffObj_termfile()
316                 :    OmfObj_termfile();
317         }
318 
319         void term(const(char)* objfilename)
320         {
321             return config.objfmt == OBJ_MSCOFF
322                 ? MsCoffObj_term(objfilename)
323                 :    OmfObj_term(objfilename);
324         }
325 
326         size_t mangle(Symbol *s,char *dest)
327         {
328             assert(config.objfmt == OBJ_OMF);
329             return OmfObj_mangle(s, dest);
330         }
331 
332         void _import(elem *e)
333         {
334             assert(config.objfmt == OBJ_OMF);
335             return OmfObj_import(e);
336         }
337 
338         void linnum(Srcpos srcpos, int seg, targ_size_t offset)
339         {
340             return config.objfmt == OBJ_MSCOFF
341                 ? MsCoffObj_linnum(srcpos, seg, offset)
342                 :    OmfObj_linnum(srcpos, seg, offset);
343         }
344 
345         int codeseg(const char *name,int suffix)
346         {
347             return config.objfmt == OBJ_MSCOFF
348                 ? MsCoffObj_codeseg(name, suffix)
349                 :    OmfObj_codeseg(name, suffix);
350         }
351 
352         void dosseg()
353         {
354             assert(config.objfmt == OBJ_OMF);
355             return OmfObj_dosseg();
356         }
357 
358         void startaddress(Symbol *s)
359         {
360             return config.objfmt == OBJ_MSCOFF
361                 ? MsCoffObj_startaddress(s)
362                 :    OmfObj_startaddress(s);
363         }
364 
365         bool includelib(const(char)* name)
366         {
367             return config.objfmt == OBJ_MSCOFF
368                 ? MsCoffObj_includelib(name)
369                 :    OmfObj_includelib(name);
370         }
371 
372         bool linkerdirective(const(char)* p)
373         {
374             return config.objfmt == OBJ_MSCOFF
375                 ? MsCoffObj_linkerdirective(p)
376                 :    OmfObj_linkerdirective(p);
377         }
378 
379         bool allowZeroSize()
380         {
381             return config.objfmt == OBJ_MSCOFF
382                 ? MsCoffObj_allowZeroSize()
383                 :    OmfObj_allowZeroSize();
384         }
385 
386         void exestr(const(char)* p)
387         {
388             return config.objfmt == OBJ_MSCOFF
389                 ? MsCoffObj_exestr(p)
390                 :    OmfObj_exestr(p);
391         }
392 
393         void user(const(char)* p)
394         {
395             return config.objfmt == OBJ_MSCOFF
396                 ? MsCoffObj_user(p)
397                 :    OmfObj_user(p);
398         }
399 
400         void compiler()
401         {
402             return config.objfmt == OBJ_MSCOFF
403                 ? MsCoffObj_compiler()
404                 :    OmfObj_compiler();
405         }
406 
407         void wkext(Symbol* s1, Symbol* s2)
408         {
409             return config.objfmt == OBJ_MSCOFF
410                 ? MsCoffObj_wkext(s1, s2)
411                 :    OmfObj_wkext(s1, s2);
412         }
413 
414         void lzext(Symbol* s1, Symbol* s2)
415         {
416             return config.objfmt == OBJ_MSCOFF
417                 ? assert(0)
418                 : OmfObj_lzext(s1, s2);
419         }
420 
421         void _alias(const(char)* n1,const(char)* n2)
422         {
423             return config.objfmt == OBJ_MSCOFF
424                 ? MsCoffObj_alias(n1, n2)
425                 :    OmfObj_alias(n1, n2);
426         }
427 
428         void theadr(const(char)* modname)
429         {
430             return config.objfmt == OBJ_MSCOFF
431                 ? assert(0)
432                 : OmfObj_theadr(modname);
433         }
434 
435         void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize)
436         {
437             return config.objfmt == OBJ_MSCOFF
438                 ? assert(0)
439                 : OmfObj_segment_group(codesize, datasize, cdatasize, udatasize);
440         }
441 
442         void staticctor(Symbol *s,int dtor,int seg)
443         {
444             return config.objfmt == OBJ_MSCOFF
445                 ? MsCoffObj_staticctor(s, dtor, seg)
446                 :    OmfObj_staticctor(s, dtor, seg);
447         }
448 
449         void staticdtor(Symbol *s)
450         {
451             return config.objfmt == OBJ_MSCOFF
452                 ? MsCoffObj_staticdtor(s)
453                 :    OmfObj_staticdtor(s);
454         }
455 
456         void setModuleCtorDtor(Symbol *s, bool isCtor)
457         {
458             return config.objfmt == OBJ_MSCOFF
459                 ? MsCoffObj_setModuleCtorDtor(s, isCtor)
460                 :    OmfObj_setModuleCtorDtor(s, isCtor);
461         }
462 
463         void ehtables(Symbol *sfunc,uint size,Symbol *ehsym)
464         {
465             return config.objfmt == OBJ_MSCOFF
466                 ? MsCoffObj_ehtables(sfunc, size, ehsym)
467                 :    OmfObj_ehtables(sfunc, size, ehsym);
468         }
469 
470         void ehsections()
471         {
472             return config.objfmt == OBJ_MSCOFF
473                 ? MsCoffObj_ehsections()
474                 :    OmfObj_ehsections();
475         }
476 
477         void moduleinfo(Symbol *scc)
478         {
479             return config.objfmt == OBJ_MSCOFF
480                 ? MsCoffObj_moduleinfo(scc)
481                 :    OmfObj_moduleinfo(scc);
482         }
483 
484         int comdat(Symbol *s)
485         {
486             return config.objfmt == OBJ_MSCOFF
487                 ? MsCoffObj_comdat(s)
488                 :    OmfObj_comdat(s);
489         }
490 
491         int comdatsize(Symbol *s, targ_size_t symsize)
492         {
493             return config.objfmt == OBJ_MSCOFF
494                 ? MsCoffObj_comdatsize(s, symsize)
495                 :    OmfObj_comdatsize(s, symsize);
496         }
497 
498         int readonly_comdat(Symbol *s)
499         {
500             return config.objfmt == OBJ_MSCOFF
501                 ? MsCoffObj_comdat(s)
502                 :    OmfObj_comdat(s);
503         }
504 
505         void setcodeseg(int seg)
506         {
507             return config.objfmt == OBJ_MSCOFF
508                 ? MsCoffObj_setcodeseg(seg)
509                 :    OmfObj_setcodeseg(seg);
510         }
511 
512         seg_data *tlsseg()
513         {
514             return config.objfmt == OBJ_MSCOFF
515                 ? MsCoffObj_tlsseg()
516                 :    OmfObj_tlsseg();
517         }
518 
519         seg_data *tlsseg_bss()
520         {
521             return config.objfmt == OBJ_MSCOFF
522                 ? MsCoffObj_tlsseg_bss()
523                 :    OmfObj_tlsseg_bss();
524         }
525 
526         seg_data *tlsseg_data()
527         {
528             return config.objfmt == OBJ_MSCOFF
529                 ? MsCoffObj_tlsseg_data()
530                 :    OmfObj_tlsseg_data();
531         }
532 
533         int  fardata(char *name, targ_size_t size, targ_size_t *poffset)
534         {
535             assert(config.objfmt == OBJ_OMF);
536             return OmfObj_fardata(name, size, poffset);
537         }
538 
539         void export_symbol(Symbol *s, uint argsize)
540         {
541             return config.objfmt == OBJ_MSCOFF
542                 ? MsCoffObj_export_symbol(s, argsize)
543                 :    OmfObj_export_symbol(s, argsize);
544         }
545 
546         void pubdef(int seg, Symbol *s, targ_size_t offset)
547         {
548             return config.objfmt == OBJ_MSCOFF
549                 ? MsCoffObj_pubdef(seg, s, offset)
550                 :    OmfObj_pubdef(seg, s, offset);
551         }
552 
553         void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize)
554         {
555             return config.objfmt == OBJ_MSCOFF
556                 ? MsCoffObj_pubdefsize(seg, s, offset, symsize)
557                 :    OmfObj_pubdefsize(seg, s, offset, symsize);
558         }
559 
560         int external_def(const(char)* name)
561         {
562             return config.objfmt == OBJ_MSCOFF
563                 ? MsCoffObj_external_def(name)
564                 :    OmfObj_external_def(name);
565         }
566 
567         int data_start(Symbol *sdata, targ_size_t datasize, int seg)
568         {
569             return config.objfmt == OBJ_MSCOFF
570                 ? MsCoffObj_data_start(sdata, datasize, seg)
571                 :    OmfObj_data_start(sdata, datasize, seg);
572         }
573 
574         int external(Symbol *s)
575         {
576             return config.objfmt == OBJ_MSCOFF
577                 ? MsCoffObj_external(s)
578                 :    OmfObj_external(s);
579         }
580 
581         int common_block(Symbol *s, targ_size_t size, targ_size_t count)
582         {
583             return config.objfmt == OBJ_MSCOFF
584                 ? MsCoffObj_common_block(s, size, count)
585                 :    OmfObj_common_block(s, size, count);
586         }
587 
588         int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count)
589         {
590             return config.objfmt == OBJ_MSCOFF
591                 ? MsCoffObj_common_block(s, flag, size, count)
592                 :    OmfObj_common_block(s, flag, size, count);
593         }
594 
595         void lidata(int seg, targ_size_t offset, targ_size_t count)
596         {
597             return config.objfmt == OBJ_MSCOFF
598                 ? MsCoffObj_lidata(seg, offset, count)
599                 :    OmfObj_lidata(seg, offset, count);
600         }
601 
602         void write_zeros(seg_data *pseg, targ_size_t count)
603         {
604             return config.objfmt == OBJ_MSCOFF
605                 ? MsCoffObj_write_zeros(pseg, count)
606                 :    OmfObj_write_zeros(pseg, count);
607         }
608 
609         void write_byte(seg_data *pseg, uint _byte)
610         {
611             return config.objfmt == OBJ_MSCOFF
612                 ? MsCoffObj_write_byte(pseg, _byte)
613                 :    OmfObj_write_byte(pseg, _byte);
614         }
615 
616         void write_bytes(seg_data *pseg, uint nbytes, void *p)
617         {
618             return config.objfmt == OBJ_MSCOFF
619                 ? MsCoffObj_write_bytes(pseg, nbytes, p)
620                 :    OmfObj_write_bytes(pseg, nbytes, p);
621         }
622 
623         void _byte(int seg, targ_size_t offset, uint _byte)
624         {
625             return config.objfmt == OBJ_MSCOFF
626                 ? MsCoffObj_byte(seg, offset, _byte)
627                 :    OmfObj_byte(seg, offset, _byte);
628         }
629 
630         uint bytes(int seg, targ_size_t offset, uint nbytes, void *p)
631         {
632             return config.objfmt == OBJ_MSCOFF
633                 ? MsCoffObj_bytes(seg, offset, nbytes, p)
634                 :    OmfObj_bytes(seg, offset, nbytes, p);
635         }
636 
637         void ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2)
638         {
639             return config.objfmt == OBJ_MSCOFF
640                 ? assert(0)
641                 : OmfObj_ledata(seg, offset, data, lcfd, idx1, idx2);
642         }
643 
644         void write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2)
645         {
646             return config.objfmt == OBJ_MSCOFF
647                 ? assert(0)
648                 : OmfObj_write_long(seg, offset, data, lcfd, idx1, idx2);
649         }
650 
651         void reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags)
652         {
653             return config.objfmt == OBJ_MSCOFF
654                 ? MsCoffObj_reftodatseg(seg, offset, val, targetdatum, flags)
655                 :    OmfObj_reftodatseg(seg, offset, val, targetdatum, flags);
656         }
657 
658         void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags)
659         {
660             return config.objfmt == OBJ_MSCOFF
661                 ? assert(0)
662                 : OmfObj_reftofarseg(seg, offset, val, farseg, flags);
663         }
664 
665         void reftocodeseg(int seg, targ_size_t offset, targ_size_t val)
666         {
667             return config.objfmt == OBJ_MSCOFF
668                 ? MsCoffObj_reftocodeseg(seg, offset, val)
669                 :    OmfObj_reftocodeseg(seg, offset, val);
670         }
671 
672         int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags)
673         {
674             return config.objfmt == OBJ_MSCOFF
675                 ? MsCoffObj_reftoident(seg, offset, s, val, flags)
676                 :    OmfObj_reftoident(seg, offset, s, val, flags);
677         }
678 
679         void far16thunk(Symbol *s)
680         {
681             return config.objfmt == OBJ_MSCOFF
682                 ? MsCoffObj_far16thunk(s)
683                 :    OmfObj_far16thunk(s);
684         }
685 
686         void fltused()
687         {
688             return config.objfmt == OBJ_MSCOFF
689                 ? MsCoffObj_fltused()
690                 :    OmfObj_fltused();
691         }
692 
693         int data_readonly(char *p, int len, int *pseg)
694         {
695             return config.objfmt == OBJ_MSCOFF
696                 ? MsCoffObj_data_readonly(p, len, pseg)
697                 :    OmfObj_data_readonly(p, len, pseg);
698         }
699 
700         int data_readonly(char *p, int len)
701         {
702             return config.objfmt == OBJ_MSCOFF
703                 ? MsCoffObj_data_readonly(p, len)
704                 :    OmfObj_data_readonly(p, len);
705         }
706 
707         int string_literal_segment(uint sz)
708         {
709             return config.objfmt == OBJ_MSCOFF
710                 ? MsCoffObj_string_literal_segment(sz)
711                 :    OmfObj_string_literal_segment(sz);
712         }
713 
714         Symbol *sym_cdata(tym_t ty, char *p, int len)
715         {
716             return config.objfmt == OBJ_MSCOFF
717                 ? MsCoffObj_sym_cdata(ty, p, len)
718                 :    OmfObj_sym_cdata(ty, p, len);
719         }
720 
721         void func_start(Symbol *sfunc)
722         {
723             return config.objfmt == OBJ_MSCOFF
724                 ? MsCoffObj_func_start(sfunc)
725                 :    OmfObj_func_start(sfunc);
726         }
727 
728         void func_term(Symbol *sfunc)
729         {
730             return config.objfmt == OBJ_MSCOFF
731                 ? MsCoffObj_func_term(sfunc)
732                 :    OmfObj_func_term(sfunc);
733         }
734 
735         void write_pointerRef(Symbol* s, uint off)
736         {
737             return config.objfmt == OBJ_MSCOFF
738                 ? MsCoffObj_write_pointerRef(s, off)
739                 :    OmfObj_write_pointerRef(s, off);
740         }
741 
742         int jmpTableSegment(Symbol* s)
743         {
744             return config.objfmt == OBJ_MSCOFF
745                 ? MsCoffObj_jmpTableSegment(s)
746                 :    OmfObj_jmpTableSegment(s);
747         }
748 
749         Symbol *tlv_bootstrap()
750         {
751             return config.objfmt == OBJ_MSCOFF
752                 ? MsCoffObj_tlv_bootstrap()
753                 :    OmfObj_tlv_bootstrap();
754         }
755 
756         void gotref(Symbol *s)
757         {
758         }
759 
760         int seg_debugT()           // where the symbolic debug type data goes
761         {
762             return config.objfmt == OBJ_MSCOFF
763                 ? MsCoffObj_seg_debugT()
764                 :    OmfObj_seg_debugT();
765         }
766 
767         /*******************************************/
768 
769         int  getsegment(const(char)* sectname, uint flags)
770         {
771             assert(config.objfmt == OBJ_MSCOFF);
772             return MsCoffObj_getsegment(sectname, flags);
773         }
774 
775         int  getsegment2(uint shtidx)
776         {
777             assert(config.objfmt == OBJ_MSCOFF);
778             return MsCoffObj_getsegment2(shtidx);
779         }
780 
781         uint addScnhdr(const(char)* scnhdr_name, uint flags)
782         {
783             assert(config.objfmt == OBJ_MSCOFF);
784             return MsCoffObj_addScnhdr(scnhdr_name, flags);
785         }
786 
787         void addrel(int seg, targ_size_t offset, Symbol *targsym,
788                               uint targseg, int rtype, int val)
789         {
790             assert(config.objfmt == OBJ_MSCOFF);
791             return MsCoffObj_addrel(seg, offset, targsym, targseg, rtype, val);
792         }
793 
794         int  seg_drectve()
795         {
796             assert(config.objfmt == OBJ_MSCOFF);
797             return MsCoffObj_seg_drectve();
798         }
799 
800         int  seg_pdata()
801         {
802             assert(config.objfmt == OBJ_MSCOFF);
803             return MsCoffObj_seg_pdata();
804         }
805 
806         int  seg_xdata()
807         {
808             assert(config.objfmt == OBJ_MSCOFF);
809             return MsCoffObj_seg_xdata();
810         }
811 
812         int  seg_pdata_comdat(Symbol *sfunc)
813         {
814             assert(config.objfmt == OBJ_MSCOFF);
815             return MsCoffObj_seg_pdata_comdat(sfunc);
816         }
817 
818         int  seg_xdata_comdat(Symbol *sfunc)
819         {
820             assert(config.objfmt == OBJ_MSCOFF);
821             return MsCoffObj_seg_xdata_comdat(sfunc);
822         }
823 
824         int  seg_debugS()
825         {
826             assert(config.objfmt == OBJ_MSCOFF);
827             return MsCoffObj_seg_debugS();
828         }
829 
830         int  seg_debugS_comdat(Symbol *sfunc)
831         {
832             assert(config.objfmt == OBJ_MSCOFF);
833             return MsCoffObj_seg_debugS_comdat(sfunc);
834         }
835       }
836     }
837 }
838 else version (ELFandMACH)
839 {
840     class Obj
841     {
842       static:
843       nothrow:
844         Obj init(Outbuffer* objbuf, const(char)* filename, const(char)* csegname)
845         {
846             return Obj_init(objbuf, filename, csegname);
847         }
848 
849         void initfile(const(char)* filename, const(char)* csegname, const(char)* modname)
850         {
851             return Obj_initfile(filename, csegname, modname);
852         }
853 
854         void termfile()
855         {
856             return Obj_termfile();
857         }
858 
859         void term(const(char)* objfilename)
860         {
861             return Obj_term(objfilename);
862         }
863 
864         /+size_t mangle(Symbol *s,char *dest)
865         {
866             return Obj_mangle(s, dest);
867         }+/
868 
869         /+void _import(elem *e)
870         {
871             return Obj_import(e);
872         }+/
873 
874         void linnum(Srcpos srcpos, int seg, targ_size_t offset)
875         {
876             return Obj_linnum(srcpos, seg, offset);
877         }
878 
879         int codeseg(const char *name,int suffix)
880         {
881             return Obj_codeseg(name, suffix);
882         }
883 
884         /+void dosseg()
885         {
886             return Obj_dosseg();
887         }+/
888 
889         void startaddress(Symbol *s)
890         {
891             return Obj_startaddress(s);
892         }
893 
894         bool includelib(const(char)* name)
895         {
896             return Obj_includelib(name);
897         }
898 
899         bool linkerdirective(const(char)* p)
900         {
901             return Obj_linkerdirective(p);
902         }
903 
904         bool allowZeroSize()
905         {
906             return Obj_allowZeroSize();
907         }
908 
909         void exestr(const(char)* p)
910         {
911             return Obj_exestr(p);
912         }
913 
914         void user(const(char)* p)
915         {
916             return Obj_user(p);
917         }
918 
919         void compiler()
920         {
921             return Obj_compiler();
922         }
923 
924         void wkext(Symbol* s1, Symbol* s2)
925         {
926             return Obj_wkext(s1, s2);
927         }
928 
929         /+void lzext(Symbol* s1, Symbol* s2)
930         {
931             return Obj_lzext(s1, s2);
932         }+/
933 
934         void _alias(const(char)* n1,const(char)* n2)
935         {
936             return Obj_alias(n1, n2);
937         }
938 
939         /+void theadr(const(char)* modname)
940         {
941             return Obj_theadr(modname);
942         }+/
943 
944         /+void segment_group(targ_size_t codesize, targ_size_t datasize, targ_size_t cdatasize, targ_size_t udatasize)
945         {
946             return Obj_segment_group(codesize, datasize, cdatasize, udatasize);
947         }+/
948 
949         void staticctor(Symbol *s,int dtor,int seg)
950         {
951             return Obj_staticctor(s, dtor, seg);
952         }
953 
954         void staticdtor(Symbol *s)
955         {
956             return Obj_staticdtor(s);
957         }
958 
959         void setModuleCtorDtor(Symbol *s, bool isCtor)
960         {
961             return Obj_setModuleCtorDtor(s, isCtor);
962         }
963 
964         void ehtables(Symbol *sfunc,uint size,Symbol *ehsym)
965         {
966             return Obj_ehtables(sfunc, size, ehsym);
967         }
968 
969         void ehsections()
970         {
971             return Obj_ehsections();
972         }
973 
974         void moduleinfo(Symbol *scc)
975         {
976             return Obj_moduleinfo(scc);
977         }
978 
979         int comdat(Symbol *s)
980         {
981             return Obj_comdat(s);
982         }
983 
984         int comdatsize(Symbol *s, targ_size_t symsize)
985         {
986             return Obj_comdatsize(s, symsize);
987         }
988 
989         int readonly_comdat(Symbol *s)
990         {
991             return Obj_comdat(s);
992         }
993 
994         void setcodeseg(int seg)
995         {
996             return Obj_setcodeseg(seg);
997         }
998 
999         seg_data *tlsseg()
1000         {
1001             return Obj_tlsseg();
1002         }
1003 
1004         seg_data *tlsseg_bss()
1005         {
1006             return Obj_tlsseg_bss();
1007         }
1008 
1009         seg_data *tlsseg_data()
1010         {
1011             return Obj_tlsseg_data();
1012         }
1013 
1014         /+int fardata(char *name, targ_size_t size, targ_size_t *poffset)
1015         {
1016             return Obj_fardata(name, size, poffset);
1017         }+/
1018 
1019         void export_symbol(Symbol *s, uint argsize)
1020         {
1021             return Obj_export_symbol(s, argsize);
1022         }
1023 
1024         void pubdef(int seg, Symbol *s, targ_size_t offset)
1025         {
1026             return Obj_pubdef(seg, s, offset);
1027         }
1028 
1029         void pubdefsize(int seg, Symbol *s, targ_size_t offset, targ_size_t symsize)
1030         {
1031             return Obj_pubdefsize(seg, s, offset, symsize);
1032         }
1033 
1034         int external_def(const(char)* name)
1035         {
1036             return Obj_external_def(name);
1037         }
1038 
1039         int data_start(Symbol *sdata, targ_size_t datasize, int seg)
1040         {
1041             return Obj_data_start(sdata, datasize, seg);
1042         }
1043 
1044         int external(Symbol *s)
1045         {
1046             return Obj_external(s);
1047         }
1048 
1049         int common_block(Symbol *s, targ_size_t size, targ_size_t count)
1050         {
1051             return Obj_common_block(s, size, count);
1052         }
1053 
1054         int common_block(Symbol *s, int flag, targ_size_t size, targ_size_t count)
1055         {
1056             return Obj_common_block(s, flag, size, count);
1057         }
1058 
1059         void lidata(int seg, targ_size_t offset, targ_size_t count)
1060         {
1061             return Obj_lidata(seg, offset, count);
1062         }
1063 
1064         void write_zeros(seg_data *pseg, targ_size_t count)
1065         {
1066             return Obj_write_zeros(pseg, count);
1067         }
1068 
1069         void write_byte(seg_data *pseg, uint _byte)
1070         {
1071             return Obj_write_byte(pseg, _byte);
1072         }
1073 
1074         void write_bytes(seg_data *pseg, uint nbytes, void *p)
1075         {
1076             return Obj_write_bytes(pseg, nbytes, p);
1077         }
1078 
1079         void _byte(int seg, targ_size_t offset, uint _byte)
1080         {
1081             return Obj_byte(seg, offset, _byte);
1082         }
1083 
1084         uint bytes(int seg, targ_size_t offset, uint nbytes, void *p)
1085         {
1086             return Obj_bytes(seg, offset, nbytes, p);
1087         }
1088 
1089         /+void ledata(int seg, targ_size_t offset, targ_size_t data, uint lcfd, uint idx1, uint idx2)
1090         {
1091             return Obj_ledata(seg, offset, data, lcfd, idx1, idx2);
1092         }+/
1093 
1094         /+void write_long(int seg, targ_size_t offset, uint data, uint lcfd, uint idx1, uint idx2)
1095         {
1096             return Obj_write_long(seg, offset, data, lcfd, idx1, idx2);
1097         }+/
1098 
1099         void reftodatseg(int seg, targ_size_t offset, targ_size_t val, uint targetdatum, int flags)
1100         {
1101             return Obj_reftodatseg(seg, offset, val, targetdatum, flags);
1102         }
1103 
1104         /+void reftofarseg(int seg, targ_size_t offset, targ_size_t val, int farseg, int flags)
1105         {
1106             return Obj_reftofarseg(seg, offset, val, farseg, flags);
1107         }+/
1108 
1109         void reftocodeseg(int seg, targ_size_t offset, targ_size_t val)
1110         {
1111             return Obj_reftocodeseg(seg, offset, val);
1112         }
1113 
1114         int reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val, int flags)
1115         {
1116             return Obj_reftoident(seg, offset, s, val, flags);
1117         }
1118 
1119         void far16thunk(Symbol *s)
1120         {
1121             return Obj_far16thunk(s);
1122         }
1123 
1124         void fltused()
1125         {
1126             return Obj_fltused();
1127         }
1128 
1129         int data_readonly(char *p, int len, int *pseg)
1130         {
1131             return Obj_data_readonly(p, len, pseg);
1132         }
1133 
1134         int data_readonly(char *p, int len)
1135         {
1136             return Obj_data_readonly(p, len);
1137         }
1138 
1139         int string_literal_segment(uint sz)
1140         {
1141             return Obj_string_literal_segment(sz);
1142         }
1143 
1144         Symbol *sym_cdata(tym_t ty, char *p, int len)
1145         {
1146             return Obj_sym_cdata(ty, p, len);
1147         }
1148 
1149         void func_start(Symbol *sfunc)
1150         {
1151             return Obj_func_start(sfunc);
1152         }
1153 
1154         void func_term(Symbol *sfunc)
1155         {
1156             return Obj_func_term(sfunc);
1157         }
1158 
1159         void write_pointerRef(Symbol* s, uint off)
1160         {
1161             return Obj_write_pointerRef(s, off);
1162         }
1163 
1164         int jmpTableSegment(Symbol* s)
1165         {
1166             return Obj_jmpTableSegment(s);
1167         }
1168 
1169         Symbol *tlv_bootstrap()
1170         {
1171             return Obj_tlv_bootstrap();
1172         }
1173 
1174         void gotref(Symbol *s)
1175         {
1176             return Obj_gotref(s);
1177         }
1178 
1179         uint addstr(Outbuffer *strtab, const(char)* p)
1180         {
1181             return Obj_addstr(strtab, p);
1182         }
1183 
1184         Symbol *getGOTsym()
1185         {
1186             return Obj_getGOTsym();
1187         }
1188 
1189         void refGOTsym()
1190         {
1191             return Obj_refGOTsym();
1192         }
1193 
1194 
1195         version (OSX)
1196         {
1197             int getsegment(const(char)* sectname, const(char)* segname,
1198                                   int align_, int flags)
1199             {
1200                 return Obj_getsegment(sectname, segname, align_, flags);
1201             }
1202 
1203             void addrel(int seg, targ_size_t offset, Symbol *targsym,
1204                                uint targseg, int rtype, int val = 0)
1205             {
1206                 return Obj_addrel(seg, offset, targsym, targseg, rtype, val);
1207             }
1208 
1209         }
1210         else
1211         {
1212             int getsegment(const(char)* name, const(char)* suffix,
1213                                   int type, int flags, int  align_)
1214             {
1215                 return Obj_getsegment(name, suffix, type, flags, align_);
1216             }
1217 
1218             void addrel(int seg, targ_size_t offset, uint type,
1219                                uint symidx, targ_size_t val)
1220             {
1221                 return Obj_addrel(seg, offset, type, symidx, val);
1222             }
1223 
1224             size_t writerel(int targseg, size_t offset, uint type,
1225                                    uint symidx, targ_size_t val)
1226             {
1227                 return Obj_writerel(targseg, offset, type, symidx, val);
1228             }
1229 
1230         }
1231     }
1232 }
1233 else version (STUB)
1234 {
1235     public import stubobj;
1236 }
1237 else
1238     static assert(0, "unsupported version");
1239 
1240 
1241 extern __gshared Obj objmod;
1242