Skip to content

Commit

Permalink
fix 879 - support for --gc-sections
Browse files Browse the repository at this point in the history
- pin .deh_eh and .minfo by emitting fake references in dso startup code

- enable --gc-sections linker switch
  • Loading branch information
MartinNowak committed May 28, 2014
1 parent 9d48c47 commit 928d92f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 20 deletions.
16 changes: 11 additions & 5 deletions src/backend/elfobj.c
Expand Up @@ -2673,8 +2673,6 @@ static size_t writeaddrval(int targseg, size_t offset, targ_size_t val, size_t s
size_t ElfObj::writerel(int targseg, size_t offset, unsigned reltype,
IDXSYM symidx, targ_size_t val)
{
assert(reltype != R_X86_64_NONE);

size_t sz;
if (I64)
{
Expand Down Expand Up @@ -3164,7 +3162,7 @@ static void obj_rtinit()
{
#if TX86
// create brackets for .deh_eh and .minfo sections
IDXSYM deh_beg, deh_end, minfo_beg, minfo_end, dso_rec;
IDXSYM deh_beg, deh, deh_end, minfo_beg, minfo, minfo_end, dso_rec;
IDXSTR namidx;
int seg;

Expand All @@ -3174,7 +3172,8 @@ static void obj_rtinit()
seg = ElfObj::getsegment(".deh_beg", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
deh_beg = MAP_SEG2SYMIDX(seg);

ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
seg = ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
deh = MAP_SEG2SYMIDX(seg);

seg = ElfObj::getsegment(".deh_end", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
deh_end = MAP_SEG2SYMIDX(seg);
Expand All @@ -3183,7 +3182,8 @@ static void obj_rtinit()
seg = ElfObj::getsegment(".minfo_beg", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
minfo_beg = MAP_SEG2SYMIDX(seg);

ElfObj::getsegment(".minfo", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
seg = ElfObj::getsegment(".minfo", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
minfo = MAP_SEG2SYMIDX(seg);

seg = ElfObj::getsegment(".minfo_end", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
minfo_end = MAP_SEG2SYMIDX(seg);
Expand Down Expand Up @@ -3444,6 +3444,12 @@ static void obj_rtinit()
// ret
buf->writeByte(0xC3);
off += 2;

// add fake references to pin .minfo and .deh_eh sections (--gc-sections)
reltype = I64 ? R_X86_64_NONE : RI_TYPE_NONE;
off += ElfObj::writerel(codseg, off, reltype, minfo, 0);
off += ElfObj::writerel(codseg, off, reltype, deh, 0);

Offset(codseg) = off;

// put a reference into .ctors/.dtors each
Expand Down
30 changes: 15 additions & 15 deletions src/link.c
Expand Up @@ -555,21 +555,21 @@ int runLINK()
argv.push(global.params.mapfile);
}

if (0 && global.params.exefile)
{
/* This switch enables what is known as 'smart linking'
* in the Windows world, where unreferenced sections
* are removed from the executable. It eliminates unreferenced
* functions, essentially making a 'library' out of a module.
* Although it is documented to work with ld version 2.13,
* in practice it does not, but just seems to be ignored.
* Thomas Kuehne has verified that it works with ld 2.16.1.
* BUG: disabled because it causes exception handling to fail
* because EH sections are "unreferenced" and elided
*/
argv.push("-Xlinker");
argv.push("--gc-sections");
}
/* This switch enables what is known as 'smart linking'
* in the Windows world, where unreferenced sections
* are removed from the executable. It eliminates unreferenced
* functions, essentially making a 'library' out of a module.
* Although it is documented to work with ld version 2.13,
* in practice it does not, but just seems to be ignored.
* Thomas Kuehne has verified that it works with ld 2.16.1.
*/
#if __linux__
/* Only works on linux because the linkers shipped with other
* OSes don't yet support this flag.
*/
argv.push("-Xlinker");
argv.push("--gc-sections");
#endif

for (size_t i = 0; i < global.params.linkswitches->dim; i++)
{ const char *p = (*global.params.linkswitches)[i];
Expand Down

0 comments on commit 928d92f

Please sign in to comment.