I am running systemtap over a 32 bit binary running in x86_64. the script is quite simple: probe process("/usr/local/bin/test").function("*").call { log (probefunc()." ".$$parms) } stage 4 fails on many of these warnings (treated as errors): warning: cast to pointer from integer of different size When looking in the generated c files I see that the failures in the function__dwarf_tvar_get_cookie_in_xxx functions. specifically in the line: { uint32_t value = deref (4, addr); u_pieces0.pieces.p4 = value; }
Could you provide the test binary for inspection?
Created attachment 433386 [details] A 32 bit Samba vfs object
Thanks. Confirmed. Also fails against latest upstream systemtap from git trunk. stap -k -p4 -e 'probe process("./unixntacl.so").function("*").call {log (probefunc()." ".$$parms)}' cc1: warnings being treated as errors /tmp/stapPR4o9H/stap_14100.c: In function ‘function__dwarf_tvar_get_offset_97’: /tmp/stapPR4o9H/stap_14100.c:2949: error: cast to pointer from integer of different size /tmp/stapPR4o9H/stap_14100.c:2949: error: cast to pointer from integer of different size /tmp/stapPR4o9H/stap_14100.c:2949: error: cast to pointer from integer of different size /tmp/stapPR4o9H/stap_14100.c:2949: error: cast to pointer from integer of different size make[1]: *** [/tmp/stapPR4o9H/stap_14100.o] Error 1 make: *** [_module_/tmp/stapPR4o9H] Error 2 Pass 4: compilation failed. Try again with another '--vp 0001' option. Keeping temporary directory "/tmp/stapPR4o9H" Where line 2949 is: { int32_t value = deref (4, addr); u_pieces0.pieces.p4 = value; } and deref is defined for __x86_64__ in runtime/loc2c-runtime.h as: #define deref(size, addr) \ ({ \ int _bad = 0; \ u8 _b; u16 _w; u32 _l; u64 _q; \ intptr_t _v = 0; \ if (lookup_bad_addr((unsigned long)addr, size)) \ _bad = 1; \ else \ switch (size) \ { \ case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break; \ case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break; \ case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break; \ case 8: __get_user_asm(_q,addr,_bad,"q","","=r",1); _v = _q; break; \ default: _v = __get_user_bad(); \ } \ if (_bad) \ DEREF_FAULT(addr); \ _v; \ })
The whole context of the generated loc2c part is: #define fetch_register u_fetch_register #define store_register u_store_register { { union { char bytes[8]; struct { uint32_t p0; uint32_t p4; } pieces __attribute__ ((packed)); uint64_t whole; } u_pieces0; uint32_t addr; { int32_t value = fetch_register (6); u_pieces0.pieces.p0 = value; } { // DWARF expression: 0x75(32) { uintptr_t s0; s0 = fetch_register (5) + 32L; addr = s0; } } { int32_t value = deref (4, addr); u_pieces0.pieces.p4 = value; } THIS->__retvalue = u_pieces0.whole; } goto out; if (0) goto deref_fault; deref_fault: goto out; }
Frank pointed out that the address fetched is 32bit (because from 32bit app), but then used by deref on a 64bit host. So the fix seems to be: diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h index 90c392d..eeb7cdb 100644 --- a/runtime/loc2c-runtime.h +++ b/runtime/loc2c-runtime.h @@ -517,10 +517,10 @@ extern void __store_deref_bad(void); else \ switch (size) \ { \ - case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break; \ - case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break; \ - case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break; \ - case 8: __get_user_asm(_q,addr,_bad,"q","","=r",1); _v = _q; break; \ + case 1: __get_user_asm(_b,(unsigned long)addr,_bad,"b","b","=q",1); _v = _b; break; \ + case 2: __get_user_asm(_w,(unsigned long)addr,_bad,"w","w","=r",1); _v = _w; break; \ + case 4: __get_user_asm(_l,(unsigned long)addr,_bad,"l","","=r",1); _v = _l; break; \ + case 8: __get_user_asm(_q,(unsigned long)addr,_bad,"q","","=r",1); _v = _q; break; \ default: _v = __get_user_bad(); \ } \ if (_bad) \
Pushed upstream: commit 31f7f175720b0756bbf022a977a1e3a687bd96da Author: Mark Wielaard <mjw> Date: Wed Jul 21 15:59:27 2010 +0200 rhbz#616040 loc2c deref on 32bit address fails. * runtime/loc2c-runtime.h (deref): For __x86_64__ case cast address to (unsigned long) everywhere in case we got a 32 bit address of a 32-on-64 but process.
This problem is fixed automatically with the rhel5.6-bound version 1.3 rebase. *** This bug has been marked as a duplicate of bug 606726 ***