Second half of the LDT support. It basically works now.
- New core uinstrs, GETSEG, PUTSEG (save and restore segment regs)
- New core uinstr USESEG, which takes a segment selector and a
virtual address, and returns a linear address -- and also does
a limit check. This calls through to VG_(use_ldt) in vg_ldt.c.
- Insn parser (disAMode) made aware of segment override prefixes
- Obvious fixes to insn emitter and translators
None of the skins understand these new uinstrs, so only --skin=none
works with them at the mo. This and some other rough edges still
need to be fixed.
First half of the long-overdue support for segment override prefixes,
LDTs and __NR_modify_ldt.
- Each thread has its own LDT. Usually NULL, but if we need to
change an entry, it is allocated. LDTs are inherited from parents
as one would expect.
- We intercept __NR_modify_ldt and update the calling thread's LDT
accordingly. This is done in coregrind/vg_ldt.c. The kernel
never sees these syscalls.
- New architectural state for %cs, %ss, %ds, %es, %fs and %gs.
Probably overkill including %cs and %ss. These are saved and
restored in the usual way, _except_ at syscalls -- there's no
point, since we are hiding all LDT operations from the kernel now.
This does assume that no syscall implicitly looks at the
segment registers, but I think that's safe.
Still only halfway there. JITter is still unaware of seg regs
and override prefixes.
Changed test so the output doesn't depend on the order in which the parent and
child run; this was random so the test was failing spuriously sometimes.
Added some reasonably thorough documentation on how to write skins. Also added
an example skin which is referred to in the documentation, and is designed to
be a template which can be copied.
Moved vg_regtest to vg_regtest.in, using autoconf so vg_regtest now knows where
the `valgrind' script is kept, so people who install valgrind in a directory
other than the one I do don't need to use the --valgrind option all the time.
As a consequence, vg_regtests is now installed in and run out of bin/, rather
than tests/.
Also added a GPL copyright notice to vg_regtests.in.
Changed the regression testing options --head and --eraser to --stable and
--dev, because the old ones were now totally confusing (since --head no longer
applies to HEAD). Had to change a couple of .vgtest "vgopt:" lines for this.
Unfortunately the --stable result files are still *.stderr.exp.hd" because
changing them via CVS is a pain.
valgrind's strcmp() implementation (to clients) treats char as signed
whereas the libc implementation it replaces treats char as unsigned.
Fix! God knows how anything much ever worked before now.
Add as many suppressions as I reasonably can for SuSE 8.1. There's
still a lot of junk, but that can only be fixed by a more direct
tackling of gcc-3.2's bad habits.
Fix stupid bug in which vg_push_signal_frame/vg_pop_signal_frame assumed
that the handler wouldn't change the signal-number parameter it was passed.
Fixes this:
vg_signals.c:1065 (vgPlain_signal_returns):
Assertion `sigNo >= 1 && sigNo <= 64' failed.
and possibly arbitrary other mutancy in the signal handling too.
Changed lots of files for the new core/ + skin/ directory structure:
- changed lots of Makefile.am files
- changed configure.in
- changed lots of #include lines for changed file names
- changed lots of file headers n footers for changed file names
- changed vg_regtest to handle new directory structure -- recursively
traverses subdirectories for .vgtest test files
- changed lots of paths in memcheck/ regression test expected outputs
vg_from_ucode.c:
- Improves the code generation for arithmetic instructions. Some arith
instructions (ADC, SBB, RCR, RCL, some FPU) read EFLAGS -- integer ops for
the carry flag, and FPU for ZCP (sometimes). But the rest don't.
Previously, the EFLAGS register was always being read before any arith
instruction, even those for which it wasn't needed. Now it's only done if
needed. This was done by splitting the anyFlagUse test used into
readFlagUse and writeFlagUse.
This results in reasonable decreases in time (3--5% for Valgrind, 12--14%
with no instrumentation) and size of translations (2%, 5%).
vg_translate.c:
- added CCALL_{1,2}_0 to a comment they were missing from.
Julian Seward [Tue, 6 Aug 2002 09:02:53 +0000 (09:02 +0000)]
Simulate resolver-specific state as per the real libpthread.so, wherein
the root thread (tid 1) always uses _res as exported from libc.so as its
state. This fixes the name lookup problems in KAtlantik.
Cache simulation requires strict INCEIP updating so that the boundaries between
individual x86 instructions can be found when instrumenting UCode. However,
EIP is not needed during execution, because the x86 instr addresses are copied
into the cost-centres. So now they INCEIPs are removed during the
instrumentation step once their task is done.
This reduces running times by about 3--7%, and translation sizes by about 9%
(code expansion reduced from about 11x to about 10x).
This commit introduces two new UInstructions: CCALL_1_0, CCALL_2_0.
These are the first of a generic family for calling C functions. CCALL_M_N
calls a function with M word-sized arguments and N word-sized return values
(N == 0 or 1, of course). All stack management is done automatically --
register saving, argument pushing, register restoring. Rough timings show it's
marginally faster (~3%), probably because the instrumentation phase is slightly
simpler and translations are slighly more compact.
It was introduced because the way Cachegrind was calling its helper functions
was not really legitimate -- it involved pushing RealRegs at a point where
RealRegs shouldn't have been used. This flukily worked for Cachegrind, but
caused obscure seg faults when I tried using the same technique for the DIDUCE
stuff. Hence this more general approach.
CCALL_M_N where M+N <= 3 are easy. More args might be done by abusing spare
fields in the UInstr struct, if really necessary. But it's not, yet.
Only run __libc_freeres() when valgrinding. It may do invalid free()s
which cause the low-level memory manager to crash. When valgrinding
that's all protected, but not when cachegrinding etc.
Some jokers apparently like setting the CPU's AC (Alignment Check) flag
for god-knows-why reasons. This causes VG_{READ,WRITE}_MISALIGNED_WORD
to give bus errors. Redefine them to do the obvious byte-by-byte loads/
stores. Fortunately they are not performance critical.
Assume PUTF modifies %EFLAGS in a completely arbitrary manner, and so
be completely pessimistic if it is encountered during the redundant-flag-
save/restore-elimination pass. This fixes the following mysterious
failure:
At request of Ulrich Drepper, call __libc_freeres() after final __NR_exit
so as to free memory allocated by glibc. This reduces the leaks reported
in glibc, but causes a stack of read/write-after-free errors which have
to be suppressed :-(
The Intel p4 manual suggests inserting a pause instruction in
spin-wait loops as a hint to what the code is doing. In other
respects it acts just like a nop. Pause (0xF3 0x90) currently
causes valgrind to panic. The patch below keeps things running.
vg_signals.c: vg_oursignalhandler(): don't longjmp() on fatal signal if
the scheduler's jmp_buf is not valid. This might avoid at least some
of the following:
vg_scheduler.c:479 (run_thread_for_a_while): Assertion `trc == 0'
failed.