[Note: this is from a amd64 -> powerpc64 cross-build based on system clang 4 instead of gcc 4.2.1. I'm building a gcc 4.2.1 based system currently so that I can test a more standard configuration. But I'm one of the ones that experiments with finding things to report for clang targeting powerpc64 and powerpc.] powerpc64 is having programs crash with an attempt to store addresses over code instead of into __cleanup_info__ when fgets is used. ntpd is an example. As is sshd (although I've looked at its details less). Building up the context for this claim. . . public declaration: struct _pthread_cleanup_info { __uintptr_t pthread_cleanup_pad[8]; }; private declaration: struct pthread_cleanup { struct pthread_cleanup *prev; void (*routine)(void *); void *routine_arg; int onheap; }; ntpd and sshd die with segmentation faults in: void __pthread_cleanup_push_imp(void (*routine)(void *), void *arg, struct _pthread_cleanup_info *info) { struct pthread *curthread = _get_curthread(); struct pthread_cleanup *newbuf; newbuf = (void *)info; newbuf->routine = routine; newbuf->routine_arg = arg; newbuf->onheap = 0; newbuf->prev = curthread->cleanup; curthread->cleanup = newbuf; } at the statement: newbuf->routine = routine; But it turns out that the bt is like: __pthread_cleanup_push_imp(routine=0x507b1248 <__stdio_cancel_cleanup>, arg=0x0, info=0x509eaaf4) __pthread_cleanup_push_imp_int(p0=0x507b1248,p1=0x0) fgets (buf=0x51415000 "", n=511, fp=0x507d4c40) . . . Note the 2 arguments to __pthread_cleanup_push_imp_int when called from fgets but the 3 arguemnts to __pthread_cleanup_push_imp . . . fgets uses FLOCK_CANCELSAFE(fp) : #define FLOCKFILE_CANCELSAFE(fp) \ { \ struct _pthread_cleanup_info __cleanup_info__; \ if (__isthreaded) { \ _FLOCKFILE(fp); \ ___pthread_cleanup_push_imp( \ __stdio_cancel_cleanup, (fp), \ &__cleanup_info__); \ } else { \ ___pthread_cleanup_push_imp( \ __stdio_cancel_cleanup, NULL, \ &__cleanup_info__); \ } \ { #define FUNLOCKFILE_CANCELSAFE() \ (void)0; \ } \ ___pthread_cleanup_pop_imp(1); \ } where here the NULL case is in use. 3 arguments. But: STUB_FUNC2(__pthread_cleanup_push_imp, PJT_CLEANUP_PUSH_IMP, void, void*, void *); which is use of: #define STUB_FUNC2(name, idx, ret, p0_type, p1_type) \ static ret FUNC_EXP(name)(p0_type, p1_type) __used; \ static ret FUNC_INT(name)(p0_type, p1_type) __used; \ WEAK_REF(FUNC_EXP(name), name); \ WEAK_REF(FUNC_INT(name), __CONCAT(_, name)); \ typedef ret (*FUNC_TYPE(name))(p0_type, p1_type); \ static ret FUNC_EXP(name)(p0_type p0, p1_type p1) \ { \ FUNC_TYPE(name) func; \ func = (FUNC_TYPE(name))__thr_jtable[idx][0]; \ return (func(p0, p1)); \ } \ static ret FUNC_INT(name)(p0_type p0, p1_type p1) \ { \ FUNC_TYPE(name) func; \ func = (FUNC_TYPE(name))__thr_jtable[idx][1]; \ return (func(p0, p1)); \ } so only 2 arguments to func (i.e., __pthread_cleanup_push_imp here). Compared to: ___pthread_cleanup_push_imp( \ __stdio_cancel_cleanup, NULL, \ &__cleanup_info__); \ As a result junk is used instead of &__cleanup_info__. On powerpc64 it happens to be the address of ___pthread_cleanup_push_imp that happens to be in r5 (normally the third argument) at the time. So: newbuf->routine = routine; tries to replace the first instruction of ___pthread_cleanup_push_imp . As far as I can tell what should be used is: #define STUB_FUNC3(name, idx, ret, p0_type, p1_type, p2_type) \ static ret FUNC_EXP(name)(p0_type, p1_type, p2_type) __used; \ static ret FUNC_INT(name)(p0_type, p1_type, p2_type) __used; \ WEAK_REF(FUNC_EXP(name), name); \ WEAK_REF(FUNC_INT(name), __CONCAT(_, name)); \ typedef ret (*FUNC_TYPE(name))(p0_type, p1_type, p2_type); \ static ret FUNC_EXP(name)(p0_type p0, p1_type p1, p2_type p2) \ { \ FUNC_TYPE(name) func; \ func = (FUNC_TYPE(name))__thr_jtable[idx][0]; \ return (func(p0, p1, p2)); \ } \ static ret FUNC_INT(name)(p0_type p0, p1_type p1, p2_type p2) \ { \ FUNC_TYPE(name) func; \ func = (FUNC_TYPE(name))__thr_jtable[idx][1]; \ return (func(p0, p1, p2)); \ } with the p2_type being: struct _pthread_cleanup_info * but I'm not expert in this code. === Mark Millard markmi at dsl-only.netReceived on Sun Jul 02 2017 - 00:42:20 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:12 UTC