#4970: time002 and time004 (ghci) test failures on OS X 64 bit
-------------------------------+--------------------------------------------
Reporter: gwright | Owner: gwright
Type: bug | Status: new
Priority: normal | Component: GHCi
Version: 7.0.1 | Keywords:
Testcase: | Blockedby:
Os: MacOS X | Blocking:
Architecture: x86_64 (amd64) | Failure: Incorrect result at runtime
-------------------------------+--------------------------------------------
Comment(by gwright):
I've replaced the old X86_64 code in `relocateSection` with new code that
provides more debug info. There is indeed an error in some of the
`X86_64_RELOC_SUBTRACTOR` cases.
The below relocation is for the symbol `ctPicosec` which is read
incorrectly by `test002`.
Here's what goes wrong:
{{{
relocateSection: relocation 4534 has
relocateSection: r_address = 146525 (0x23c5d)
relocateSection: r_symbolnum = 4307 (0x10d3)
relocateSection: r_pcrel = 0
relocateSection: r_length = 2
relocateSection: r_extern = 1
relocateSection: r_type = 0 (0)
relocateSection: fixupPtr = 0x10611fe8d, fixup = 0xf9ee01c0, pc =
0x10611fe91
relocateSection: type is X86_64_RELOC_UNSIGNED
findSymbolAddress: looking for symbol
_oldzmtimezm1zi0zi0zi6_SystemziTime_ctPicosec_info
findSymbolAddress: _oldzmtimezm1zi0zi0zi6_SystemziTime_ctPicosec_info
is defined in this object file
findSymbolAddress: oc->image = 0x1060fc000
findSymbolAddress: section[0].offset = 0x230
findSymbolAddress: section[0].addr = 0
findSymbolAddress: symbol->n_value = 0x23c28
relocateSection: external symbol
_oldzmtimezm1zi0zi0zi6_SystemziTime_ctPicosec_info found at 10611fe58
relocateSection: FINAL: reloc = 4534, addr = 23c5d, fixup = 200000018
relocateSection: 32 bit reloc, fixup 0x18 written to 0x10611fe8d
}}}
Note the last two lines. The one beginning with `FINAL:` has fixup
0x200000018, but the next line shows that 0x18 was written back to the
fixup location. So the fixup has been truncated.
It's not clear from the Apple documentation what's supposed to happen
here. In my code now and in Wolfgang Thaller's earlier code, the
subtractor relocation subtracted the symbol address from the fixup, then
wrote it back to the fixup, truncating to 32 bits (`reloc->r_length == 2`,
which means the fixup is 32 bits long). The following
`X86_64_RELOC_UNSIGNED` read the saved fixup again, added the next symbol
value and truncated the result to 32 bits again. This is probably wrong.
What I think should happen is that the first `X86_64_RELOC_SUBTRACTOR`
should look up the target symbol, then save its full 64 bit value. The
following `X86_64_RELOC_UNSIGNED` should look up its symbol, then do a 64
bit subtraction of the previous symbol's address from the current one.
This difference should be added to the fixup, and the entire value
truncated to 32 bits.
This is not hard to test, and I will also add checks that will barf if a
relocation is truncated.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4970#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs