Skip to content

Commit

Permalink
Merge pull request #5359 from WalterBright/dwarfeh32
Browse files Browse the repository at this point in the history
DwarfEH: 32 bit Linux support
  • Loading branch information
andralex committed Jan 27, 2016
2 parents 30073ce + 145289f commit e270c16
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/backend/backconfig.c
Expand Up @@ -100,7 +100,7 @@ void out_config_init(
else
{
config.exe = EX_LINUX;
config.ehmethod = EH_DM;
config.ehmethod = EH_DWARF;
if (!exe)
config.flags |= CFGromable; // put switch tables in code segment
}
Expand Down
7 changes: 6 additions & 1 deletion src/backend/cgcod.c
Expand Up @@ -790,7 +790,12 @@ code *prolog()
regm_t topush = fregsaved & ~mfuncreg; // mask of registers that need saving
pushoffuse = false;
pushoff = NDPoff;
if (config.flags4 & CFG4speed && (I32 || I64))
/* We don't keep track of all the pushes and pops in a function. Hence,
* using POP REG to restore registers in the epilog doesn't work, because the Dwarf unwinder
* won't be setting ESP correctly. With pushoffuse, the registers are restored
* from EBP, which is kept track of properly.
*/
if ((config.flags4 & CFG4speed || config.ehmethod == EH_DWARF) && (I32 || I64))
{
/* Instead of pushing the registers onto the stack one by one,
* allocate space in the stack frame and copy/restore them there.
Expand Down
9 changes: 5 additions & 4 deletions src/backend/dwarf.c
Expand Up @@ -814,8 +814,9 @@ void writeEhFrameFDE(IDXSEC dfseg, Symbol *sfunc)
buf->write32(length); // Length (no Extended Length)
buf->write32((startsize + 4) - CIE_offset); // CIE Pointer
#if ELFOBJ
buf->write32(0); // address of function
ElfObj::addrel(dfseg, startsize + 8, R_X86_64_PC32, MAP_SEG2SYMIDX(sfunc->Sseg), sfunc->Soffset);
int fixup = I64 ? R_X86_64_PC32 : R_386_PC32;
buf->write32(I64 ? 0 : sfunc->Soffset); // address of function
ElfObj::addrel(dfseg, startsize + 8, fixup, MAP_SEG2SYMIDX(sfunc->Sseg), sfunc->Soffset);
//ElfObj::reftoident(dfseg, startsize + 8, sfunc, 0, CFpc32 | CFoff); // PC_begin
#else
assert(0); // not supported yet
Expand All @@ -826,11 +827,11 @@ void writeEhFrameFDE(IDXSEC dfseg, Symbol *sfunc)
buf->writeByten(4); // Augmentation Data Length
int etseg = dwarf_getsegment_alloc(except_table_name, 1);
// if CFG3pic, fixup should be R_X86_64_PC32
buf->write32(0); // address of LSDA (".gcc_except_table")
buf->write32(I64 ? 0 : sfunc->Sfunc->LSDAoffset); // address of LSDA (".gcc_except_table")
if (config.flags3 & CFG3pic)
{
#if ELFOBJ
ElfObj::addrel(dfseg, buf->size() - 4, R_X86_64_PC32, MAP_SEG2SYMIDX(etseg), sfunc->Sfunc->LSDAoffset);
ElfObj::addrel(dfseg, buf->size() - 4, fixup, MAP_SEG2SYMIDX(etseg), sfunc->Sfunc->LSDAoffset);
#else
assert(0); // not supported yet
#endif
Expand Down
10 changes: 4 additions & 6 deletions src/backend/elfobj.c
Expand Up @@ -2888,7 +2888,7 @@ int Obj::reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val,
case SCglobal:
if (!s->Sxtrnnum)
{ // not in symbol table yet - class might change
//dbg_printf("\tadding %s to fixlist\n",s->Sident);
//printf("\tadding %s to fixlist\n",s->Sident);
size_t numbyteswritten = addtofixlist(s,offset,seg,val,flags);
assert(numbyteswritten == retsize);
return retsize;
Expand Down Expand Up @@ -3507,8 +3507,6 @@ void Obj::gotref(symbol *s)
*/
int dwarf_reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val)
{
assert(I64); // I32 not implemented yet

if (config.flags3 & CFG3pic)
{
/* fixup: R_X86_64_PC32 sym="DW.ref.name"
Expand All @@ -3520,10 +3518,10 @@ int dwarf_reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val)
*/
if (!s->Sdw_ref_idx)
{
int dataDWref_seg = ElfObj::getsegment(".data.DW.ref.", s->Sident, SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 8);
int dataDWref_seg = ElfObj::getsegment(".data.DW.ref.", s->Sident, SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, I64 ? 8 : 4);
Outbuffer *buf = SegData[dataDWref_seg]->SDbuf;
assert(buf->size() == 0);
ElfObj::reftoident(dataDWref_seg, 0, s, 0, CFoffset64);
ElfObj::reftoident(dataDWref_seg, 0, s, 0, I64 ? CFoffset64 : CFoff);

// Add "DW.ref." ~ name to the symtab_strings table
IDXSTR namidx = symtab_strings->size();
Expand All @@ -3533,7 +3531,7 @@ int dwarf_reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val)

s->Sdw_ref_idx = elf_addsym(namidx, val, 8, STT_OBJECT, STB_WEAK, MAP_SEG2SECIDX(dataDWref_seg), STV_HIDDEN);
}
ElfObj::writerel(seg, offset, R_X86_64_PC32, s->Sdw_ref_idx, 0);
ElfObj::writerel(seg, offset, I64 ? R_X86_64_PC32 : R_386_PC32, s->Sdw_ref_idx, 0);
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/target.d
Expand Up @@ -84,7 +84,7 @@ struct Target
if (global.params.is64bit && global.params.isWindows)
c_long_doublesize = 8;

cppExceptions = global.params.dwarfeh || (global.params.is64bit && global.params.isLinux);
cppExceptions = global.params.dwarfeh || global.params.isLinux;
}

/******************************
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/fail3753.d
Expand Up @@ -31,7 +31,7 @@ void main()
version (Win32) static assert(0);
version (linux)
{
version (X86_64) static assert(0);
static assert(0);
}
}
else
Expand Down
3 changes: 3 additions & 0 deletions test/runnable/foreach5.d
Expand Up @@ -967,6 +967,7 @@ void test12932() @nogc

void test13756()
{
printf("test13756()\n");
int[int] org = [1:2], aa;

aa = org.dup;
Expand Down Expand Up @@ -1075,6 +1076,7 @@ auto scoped14653(T, A...)(A args)

void test14653()
{
printf("test14653()\n");
foreach (e; scoped14653!RangeClass14653(1))
{
result14653 ~= "b";
Expand Down Expand Up @@ -1110,6 +1112,7 @@ int main()
test11291();
test12103();
test12739();
printf("test12932()\n");
test12932();
test13756();
test14653();
Expand Down

0 comments on commit e270c16

Please sign in to comment.