Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/backend/cgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,10 +727,6 @@ STATIC int outfixlist_dg(void *parameter, void *pkey, void *pvalue)
}
s->Sclass = SCextern; /* make it external */
objmod->external(s);
if (s->Sflags & SFLweak)
{
objmod->wkext(s, NULL);
}
}
#if TARGET_OSX
symbol *funcsymsave = funcsym_p;
Expand Down
20 changes: 6 additions & 14 deletions src/backend/cgobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,10 +1236,9 @@ STATIC void obj_defaultlib()

/*******************************
* Output a weak extern record.
* s1 is the weak extern, s2 is its default resolution.
*/

void Obj::wkext(Symbol *s1,Symbol *s2)
static void wkext(Symbol *s1)
{
//printf("Obj::wkext(%s)\n", s1->Sident);
if (I32)
Expand All @@ -1248,25 +1247,16 @@ void Obj::wkext(Symbol *s1,Symbol *s2)
return;
}

int x2;
if (s2)
x2 = s2->Sxtrnnum;
else
{
if (!obj.nullext)
{
obj.nullext = Obj::external_def("__nullext");
}
x2 = obj.nullext;
}
if (!obj.nullext)
obj.nullext = objmod->external_def("__nullext");
outextdata();

char buffer[2+2+2];
buffer[0] = 0x80;
buffer[1] = 0xA8;
int i = 2;
i += insidx(&buffer[2],s1->Sxtrnnum);
i += insidx(&buffer[i],x2);
i += insidx(&buffer[i],obj.nullext);
objrecord(COMENT,buffer,i);
}

Expand Down Expand Up @@ -2524,6 +2514,8 @@ int Obj::external(Symbol *s)
e[len] = 0; // typidx = 0
obj.extdatai += len + 1;
s->Sxtrnnum = ++obj.extidx;
if (s->Sflags & SFLweak)
wkext(s);
return obj.extidx;
}

Expand Down
6 changes: 3 additions & 3 deletions src/backend/cod1.c
Original file line number Diff line number Diff line change
Expand Up @@ -2314,9 +2314,9 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask)
if (I16 && // bug in Optlink for weak references
config.flags3 & CFG3wkfloat &&
(info[clib].flags & (INFfloat | INFwkdone)) == INFfloat)
{ info[clib].flags |= INFwkdone;
makeitextern(rtlsym[RTLSYM_INTONLY]);
objmod->wkext(s,rtlsym[RTLSYM_INTONLY]);
{
info[clib].flags |= INFwkdone;
objmod->external(s,rtlsym[RTLSYM_INTONLY]);
}
#endif
}
Expand Down
12 changes: 1 addition & 11 deletions src/backend/elfobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -1492,15 +1492,6 @@ void Obj::user(const char *p)
//dbg_printf("Obj::user(char *%s)\n",p);
}

/*******************************
* Output a weak extern record.
*/

void Obj::wkext(Symbol *s1,Symbol *s2)
{
//dbg_printf("Obj::wkext(Symbol *%s,Symbol *s2)\n",s1->Sident,s2->Sident);
}

/*******************************
* Output file name record.
*
Expand Down Expand Up @@ -2285,9 +2276,8 @@ int Obj::external(Symbol *s)
}

s->Sxtrnnum = elf_addsym(namidx, size, size, symtype,
/*(s->ty() & mTYweak) ? STB_WEAK : */STB_GLOBAL, sectype);
(s->Sflags & SFLweak) ? STB_WEAK : STB_GLOBAL, sectype);
return s->Sxtrnnum;

}

/*******************************
Expand Down
11 changes: 2 additions & 9 deletions src/backend/machobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,8 @@ void Obj::term(const char *objfilename)
sym.n_type = N_EXT | N_UNDF;
sym.n_desc = tyfunc(s->ty()) ? REFERENCE_FLAG_UNDEFINED_LAZY
: REFERENCE_FLAG_UNDEFINED_NON_LAZY;
if (s->Sflags & SFLweak)
sym.n_desc |= N_WEAK_REF;
sym.n_sect = 0;
if (I64)
fobjbuf->write(&sym, sizeof(sym));
Expand Down Expand Up @@ -1484,15 +1486,6 @@ void Obj::user(const char *p)
//dbg_printf("Obj::user(char *%s)\n",p);
}

/*******************************
* Output a weak extern record.
*/

void Obj::wkext(Symbol *s1,Symbol *s2)
{
//dbg_printf("Obj::wkext(Symbol *%s,Symbol *s2)\n",s1->Sident,s2->Sident);
}

/*******************************
* Output file name record.
*
Expand Down
1 change: 1 addition & 0 deletions src/backend/mscoff.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ struct syment
#define IMAGE_SYM_CLASS_LABEL 6
#define IMAGE_SYM_CLASS_FUNCTION 101
#define IMAGE_SYM_CLASS_FILE 103
#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105

unsigned char n_numaux;
};
Expand Down
16 changes: 7 additions & 9 deletions src/backend/mscoffobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,13 @@ void build_syment_table(bool bigobj)
sym.n_value = s->Soffset;
break;

case SCcomdat:
case SCcomdef:
sym.n_sclass = IMAGE_SYM_CLASS_WEAK_EXTERNAL;
if (sym.n_scnum != IMAGE_SYM_UNDEFINED)
sym.n_value = s->Soffset;
break;

default:
sym.n_sclass = IMAGE_SYM_CLASS_EXTERNAL;
if (sym.n_scnum != IMAGE_SYM_UNDEFINED)
Expand Down Expand Up @@ -1219,15 +1226,6 @@ void MsCoffObj::user(const char *p)
//dbg_printf("MsCoffObj::user(char *%s)\n",p);
}

/*******************************
* Output a weak extern record.
*/

void MsCoffObj::wkext(Symbol *s1,Symbol *s2)
{
//dbg_printf("MsCoffObj::wkext(Symbol *%s,Symbol *s2)\n",s1->Sident,s2->Sident);
}

/*******************************
* Output file name record.
*
Expand Down
3 changes: 0 additions & 3 deletions src/backend/obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ struct Obj
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);
Expand Down Expand Up @@ -135,7 +134,6 @@ struct MsCoffObj : Obj
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);
Expand All @@ -154,7 +152,6 @@ struct MsCoffObj : Obj
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 *);
Expand Down
2 changes: 1 addition & 1 deletion src/backend/rtlsym.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ SYMBOL_SCPP(AHSHIFT, FLfunc,0,"_AHSHIFT",0,tstrace) \
\
SYMBOL_SCPP_TX86(HDIFFN, FLfunc,mBX|mCX|mSI|mDI|mBP|mES,"_aNahdiff", 0, 0) \
SYMBOL_SCPP_TX86(HDIFFF, FLfunc,mBX|mCX|mSI|mDI|mBP|mES,"_aFahdiff", 0, 0) \
SYMBOL_SCPP_TX86(INTONLY,FLfunc,mSI|mDI,"_intonly", 0, 0) \
SYMBOL_SCPP_TX86(INTONLY,FLfunc,mSI|mDI,"_intonly", SFLweak, 0) \
\
SYMBOL_Z(EXCEPT_LIST, FLextern,0,"_except_list",0,tsint) \
SYMBOL_Z(SETJMP3, FLfunc,FREGSAVED,"_setjmp3", 0, 0) \
Expand Down
14 changes: 7 additions & 7 deletions src/toobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,9 @@ void genModuleInfo(Module *m)
continue;

Symbol *s = toSymbol(mod);

/* Weak references don't pull objects in from the library,
* they resolve to 0 if not pulled in by something else.
* Don't pull in a module just because it was imported.
*/
s->Sflags |= SFLweak;
// Ideally we'd use weak linkage for ModuleInfos, but as
// they contain the list ctors/dtors, they need to be
// linked whenever something of the module is used.
dtxoff(&dt, s, 0, TYnptr);
}
}
Expand All @@ -188,7 +185,10 @@ void genModuleInfo(Module *m)
for (size_t i = 0; i < aclasses.dim; i++)
{
ClassDeclaration *cd = aclasses[i];
dtxoff(&dt, toSymbol(cd), 0, TYnptr);
Symbol *s = toSymbol(cd);
// use weak reference to reduce size of static binaries
s->Sflags |= SFLweak;
dtxoff(&dt, s, 0, TYnptr);
}
}
if (flags & MIname)
Expand Down
5 changes: 5 additions & 0 deletions test/runnable/extra-files/lib14555.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module lib14555;

shared static this() {} // needs ModuleInfo
class A {}
class B {}
8 changes: 8 additions & 0 deletions test/runnable/extra-files/test14555.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import lib14555;

void main()
{
auto dummyLinkA = new A();
assert(Object.factory("lib14555.A") !is null);
assert(Object.factory("lib14555.B") is null);
}
20 changes: 20 additions & 0 deletions test/runnable/test14555.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

src=runnable${SEP}extra-files
dir=${RESULTS_DIR}${SEP}runnable
output_file=${dir}/test14555.sh.out

if [ $OS == "win32" -o $OS == "win64" ]; then
LIBEXT=.lib
else
LIBEXT=.a
fi
libname=${dir}${SEP}lib14555${LIBEXT}

$DMD -m${MODEL} -I${src} -of${libname} -lib ${src}${SEP}lib14555.d || exit 1
$DMD -m${MODEL} -I${src} -of${dir}${SEP}test14555${EXE} ${src}${SEP}test14555.d ${libname} || exit 1
./${dir}${SEP}test14555${EXE} || exit 1

rm ${dir}/{lib14555${LIBEXT},test14555${OBJ},test14555${EXE}}

echo Success >${output_file}