New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Issue 4181 - GDB prints wrong value of TLS variables #4053
Conversation
{ | ||
#if ELFOBJ | ||
ElfObj::addrel(seg, offset, R_X86_64_DTPOFF32, MAP_SEG2SYMIDX(targseg), val); | ||
#elif MACHOBJ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I64 ? R_X86_64_DTPOFF32 : RI_TYPE_TLS_LDO_32
I want to support newer Dwarf versions at some point. |
void dwarf_addrel_tls(int seg, targ_size_t offset, int targseg, targ_size_t val = 0) | ||
{ | ||
#if ELFOBJ | ||
ElfObj::addrel(seg, offset, I64 ? R_X86_64_DTPOFF32 : RI_TYPE_TLS_LDO_32, MAP_SEG2SYMIDX(targseg), val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be R_X86_64_DTPOFF64?
I still get |
On Wed, 8 Oct 2014, Martin Nowak wrote:
What system and gdb version ? What info address 'module.tlsvar' shows ? |
I just broke your pull merging #3814, you simply have to replace the RI_TYPE_ constants with R_386_. |
GNU gdb (GDB) Fedora 7.7.1-19.fc20
|
The offset readelf --segments test
|
I've tried, but it produces an error (absolute address) similar to your report. Edit: R_X86_64_DTPOFF32 is a workaround for ld.bfd v2.22. Recent binutils (2.25.51, probably since 2.24) work with R_X86_64_DTPOFF64 |
This is caused by ld.gold linker. ld.bfd works, I've tried it on Fedora. |
Sorry for the noise, the problem only happened with R_X86_64_DTPOFF64 instead of R_X86_64_DTPOFF32. |
dwarf_addrel(infoseg,infobuf->size(),s->Sseg); | ||
append_addr(infobuf, 0); // address of global | ||
// append DW_OP_GNU_push_tls_address for tls variables | ||
if (s->Sfl == FLtlsdata) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only applies to ELF.
Also there is no need to add all those dwarf_appreladdr_tls functions when they are only used once.
I'd propose this instead.
#if ELFOBJ
assert(s->Sxtrnnum);
if (s->Sfl == FLtlsdata)
{
if (I64)
{
infobuf->writeByte(DW_OP_const8u);
ElfObj::addrel(infoseg, infobuf->size(), R_X86_64_DTPOFF32, s->Sxtrnnum, 0);
infobuf->write64(0);
}
else
{
infobuf->writeByte(DW_OP_const4u);
ElfObj::addrel(infoseg, infobuf->size(), R_386_TLS_LDO_32, s->Sxtrnnum, 0);
infobuf->write32(0);
}
infobuf->writeByte(0xe0); // DW_OP_GNU_push_tls_address
}
else
#endif
{
infobuf->writeByte(DW_OP_addr);
dwarf_addrel(infoseg,infobuf->size(),s->Sseg);
append_addr(infobuf, s->Soffset); // address of global
}
- add DWARF_VERSION to dwarf.h - emit DW_OP_GNU_push_tls_address or DW_OP_form_tls_address based on DWARF_VERSION
Redone based on Martin's suggestions. Looks much cleaner. |
Fix Issue 4181 - GDB prints wrong value of TLS variables
Great, thanks a lot. |
infobuf->writeByte(DW_OP_form_tls_address); | ||
#endif | ||
} else | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this break DDMD? @yebblies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, because the backend doesn't get converted.
https://issues.dlang.org/show_bug.cgi?id=4181
Add DW_OP_GNU_push_tls_address to dwarf debug info for tls vars and also add offset to the address in append_addr() which fixes shared global vars.
I'm novice in dmd and dwarf hacking, so please review thoroughly.
Works for me on Debian wheezy x86 and x86_64, dmd 2.066 and master, gdb 7.8.50.