Skip to content

Commit

Permalink
use linker generated section brackets
Browse files Browse the repository at this point in the history
- rename sections to "minfo" and "deh"
- use hidden undefined __start/stop_minfo/deh
  to get start and end of sections
- linker will define those symbols
  (see http://www.airs.com/blog/archives/56)
- drop _Dmodule_ref initializers
  • Loading branch information
MartinNowak committed Sep 6, 2015
1 parent f82f9af commit 8a9ccd2
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 93 deletions.
124 changes: 31 additions & 93 deletions src/backend/elfobj.c
Expand Up @@ -74,8 +74,7 @@ char *obj_mangle2(Symbol *s,char *dest);

/**
* If set the compiler requires full druntime support of the new
* section registration and will no longer create global bracket
* symbols (_deh_beg,_deh_end,_tlsstart,_tlsend).
* section registration.
*/
#define REQUIRE_DSO_REGISTRY (DMDV2 && (TARGET_LINUX || TARGET_FREEBSD))

Expand Down Expand Up @@ -121,13 +120,14 @@ static void objfile_write(FILE *fd, void *buffer, unsigned len);
STATIC char * objmodtoseg (const char *modname);
STATIC void objfixupp (struct FIXUP *);
STATIC void ledata_new (int seg,targ_size_t offset);
void obj_tlssections();
STATIC void obj_tlssections();
#if MARS
static void obj_rtinit();
#endif

static IDXSYM elf_addsym(IDXSTR sym, targ_size_t val, unsigned sz,
unsigned typ,unsigned bind,IDXSEC sec);
unsigned typ,unsigned bind,IDXSEC sec,
unsigned char visibility=STV_DEFAULT);
static long elf_align(targ_size_t size, long offset);

// The object file is built is several separate pieces
Expand Down Expand Up @@ -463,13 +463,15 @@ static IDXSTR elf_addmangled(Symbol *s)
* sz = symbol size
* typ = symbol type
* bind = symbol binding
* segidx = segment index for segment where symbol is defined
* sec = index of section where symbol is defined
* visibility = visibility of symbol (STV_xxxx)
*
* Returns the symbol table index for the symbol
*/

static IDXSYM elf_addsym(IDXSTR nam, targ_size_t val, unsigned sz,
unsigned typ, unsigned bind, IDXSEC sec)
unsigned typ, unsigned bind, IDXSEC sec,
unsigned char visibility /*= STV_DEFAULT*/)
{
//dbg_printf("elf_addsym(nam %d, val %d, sz %x, typ %x, bind %x, sec %d\n",
//nam,val,sz,typ,bind,sec);
Expand Down Expand Up @@ -506,7 +508,7 @@ static IDXSYM elf_addsym(IDXSTR nam, targ_size_t val, unsigned sz,
sym.st_value = val;
sym.st_size = sz;
sym.st_info = ELF64_ST_INFO(bind,typ);
sym.st_other = 0;
sym.st_other = visibility;
sym.st_shndx = sec;
SYMbuf->write(&sym,sizeof(sym));
}
Expand All @@ -521,7 +523,7 @@ static IDXSYM elf_addsym(IDXSTR nam, targ_size_t val, unsigned sz,
sym.st_value = val;
sym.st_size = sz;
sym.st_info = ELF32_ST_INFO(bind,typ);
sym.st_other = 0;
sym.st_other = visibility;
sym.st_shndx = sec;
SYMbuf->write(&sym,sizeof(sym));
}
Expand Down Expand Up @@ -1604,11 +1606,9 @@ void Obj::ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym)

// needs to be writeable for PIC code, see Bugzilla 13117
const int shf_flags = SHF_ALLOC | SHF_WRITE;
ElfObj::getsegment(".deh_beg", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
int seg = ElfObj::getsegment(".deh_eh", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
const int seg = ElfObj::getsegment("deh", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
ehtab_entry->Sseg = seg;
Outbuffer *buf = SegData[seg]->SDbuf;
ElfObj::getsegment(".deh_end", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
ehtab_entry->Stype->Tmangle = mTYman_c;
ehsym->Stype->Tmangle = mTYman_c;

Expand All @@ -1621,34 +1621,19 @@ void Obj::ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym)
}

/*********************************************
* Put out symbols that define the beginning/end of the .deh_eh section.
* Don't need to generate section brackets, use __start_SEC/__stop_SEC instead.
*/

void Obj::ehsections()
{
// needs to be writeable for PIC code, see Bugzilla 13117
const int shf_flags = SHF_ALLOC | SHF_WRITE;
int sec = ElfObj::getsegment(".deh_beg", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
//Obj::bytes(sec, 0, 4, NULL);

IDXSTR namidx = Obj::addstr(symtab_strings,"_deh_beg");
elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec));
//elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec));

ElfObj::getsegment(".deh_eh", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);

sec = ElfObj::getsegment(".deh_end", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
namidx = Obj::addstr(symtab_strings,"_deh_end");
elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec));

obj_tlssections();
}

/*********************************************
* Put out symbols that define the beginning/end of the thread local storage sections.
*/

void obj_tlssections()
STATIC void obj_tlssections()
{
IDXSTR namidx;
int align = I64 ? 16 : 4;
Expand Down Expand Up @@ -3118,10 +3103,7 @@ long elf_align(targ_size_t size,long foffset)
}

/***************************************
* Stuff pointer to ModuleInfo in its own segment (.minfo). Always
* bracket them in .minfo_beg/.minfo_end segments. As the section
* names are non-standard the linker will map their order to the
* output sections.
* Stuff pointer to ModuleInfo into its own section (minfo).
*/

#if MARS
Expand All @@ -3130,55 +3112,11 @@ void Obj::moduleinfo(Symbol *scc)
{
const int CFflags = I64 ? (CFoffset64 | CFoff) : CFoff;

{
// needs to be writeable for PIC code, see Bugzilla 13117
const int shf_flags = SHF_ALLOC | SHF_WRITE;
ElfObj::getsegment(".minfo_beg", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
const int seg = ElfObj::getsegment(".minfo", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
ElfObj::getsegment(".minfo_end", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
SegData[seg]->SDoffset +=
reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFflags);
}

#if !REQUIRE_DSO_REGISTRY
int codeOffset, refOffset;

/* Put in the ModuleReference. */
{
/* struct ModuleReference
* {
* void* next;
* ModuleReference* module;
* }
*/
const int seg = DATA;
alignOffset(seg, NPTRSIZE);
SegData[seg]->SDoffset = SegData[seg]->SDbuf->size();
refOffset = SegData[seg]->SDoffset;
SegData[seg]->SDbuf->writezeros(NPTRSIZE);
SegData[seg]->SDoffset += NPTRSIZE;
SegData[seg]->SDoffset += Obj::reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFflags);
}

{
const int seg = CODE;
Outbuffer *buf = SegData[seg]->SDbuf;
SegData[seg]->SDoffset = buf->size();
codeOffset = SegData[seg]->SDoffset;

cod3_buildmodulector(buf, codeOffset, refOffset);

SegData[seg]->SDoffset = buf->size();
}

/* Add reference to constructor into ".ctors" segment
*/
const int seg = ElfObj::getsegment(".ctors", NULL, SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, NPTRSIZE);

const unsigned relinfo = I64 ? R_X86_64_64 : R_386_32;
const size_t sz = ElfObj::writerel(seg, SegData[seg]->SDoffset, relinfo, STI_TEXT, codeOffset);
SegData[seg]->SDoffset += sz;
#endif // !REQUIRE_DSO_REGISTRY
// needs to be writeable for PIC code, see Bugzilla 13117
const int shf_flags = SHF_ALLOC | SHF_WRITE;
const int seg = ElfObj::getsegment("minfo", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
SegData[seg]->SDoffset +=
reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFflags);
}


Expand All @@ -3192,7 +3130,8 @@ void Obj::moduleinfo(Symbol *scc)
static void obj_rtinit()
{
#if TX86
// create brackets for .deh_eh and .minfo sections
// section start/stop symbols are defined by the linker (http://www.airs.com/blog/archives/56)
// make the symbols hidden so that each DSO gets it's own brackets
IDXSYM deh_beg, deh_end, minfo_beg, minfo_end, dso_rec;
IDXSTR namidx;
int seg;
Expand All @@ -3201,22 +3140,21 @@ static void obj_rtinit()
// needs to be writeable for PIC code, see Bugzilla 13117
const int shf_flags = SHF_ALLOC | SHF_WRITE;

seg = ElfObj::getsegment(".deh_beg", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
deh_beg = MAP_SEG2SYMIDX(seg);

ElfObj::getsegment(".deh_eh", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
namidx = Obj::addstr(symtab_strings,"__start_deh");
deh_beg = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_GLOBAL, SHN_UNDEF, STV_HIDDEN);

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

namidx = Obj::addstr(symtab_strings,"__stop_deh");
deh_end = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_GLOBAL, SHN_UNDEF, STV_HIDDEN);

seg = ElfObj::getsegment(".minfo_beg", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
minfo_beg = MAP_SEG2SYMIDX(seg);
namidx = Obj::addstr(symtab_strings,"__start_minfo");
minfo_beg = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_GLOBAL, SHN_UNDEF, STV_HIDDEN);

ElfObj::getsegment(".minfo", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
ElfObj::getsegment("minfo", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);

seg = ElfObj::getsegment(".minfo_end", NULL, SHT_PROGBITS, shf_flags, NPTRSIZE);
minfo_end = MAP_SEG2SYMIDX(seg);
namidx = Obj::addstr(symtab_strings,"__stop_minfo");
minfo_end = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_GLOBAL, SHN_UNDEF, STV_HIDDEN);
}

// create section group
Expand Down
4 changes: 4 additions & 0 deletions src/backend/melf.h
Expand Up @@ -172,6 +172,10 @@ typedef struct
#define STT_LOPROC 13 /* Start of processor-specific */
#define STT_HIPROC 15 /* End of processor-specific */

#define STV_DEFAULT 0 /* Default symbol visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Sym unavailable in other modules */
#define STV_PROTECTED 3 /* Not preemptible, not exported */

unsigned char st_other; /* Currently not defined */
Elf32_Half st_shndx; /* SHT index for symbol definition */
Expand Down

0 comments on commit 8a9ccd2

Please sign in to comment.