{******************************************************************** * Workaround for the Integrated Debugger Libc.execve bug * * * * (C) 2003 Andreas Hausladen (Andreas.Hausladen@gmx.de) * * * * * * This software is provided 'as-is', without any express or * * implied warranty. In no event will the author be held liable * * for any damages arising from the use of this software. * * * * Permission is granted to anyone to use this software for any * * purpose, including commercial applications, and to alter it * * and redistribute it freely, subject to the following * * restrictions: * * * * 1. The origin of this software must not be misrepresented, * * you must not claim that you wrote the original software. * * If you use this software in a product, an acknowledgment * * in the product documentation would be appreciated but is * * not required. * * * * 2. Altered source versions must be plainly marked as such, and * * must not be misrepresented as being the original software. * * * * 3. This notice may not be removed or altered from any source * * distribution. * * * ********************************************************************} unit LibcExec; {$ALIGN 8} {$DEBUGINFO OFF} {$RANGECHECKS OFF} {$OVERFLOWCHECKS OFF} {$STACKFRAMES OFF} interface implementation {$IFDEF LINUX} uses Libc; const SYS_execve = 11; {$OPTIMIZATION OFF} function __execve(PathName: PChar; const argv: PPChar; const envp: PPChar): Integer; cdecl; begin { Do exactly the same things that the original execve@GLIBC_2.1 does. } pthread_kill_other_threads_np; Result := Libc.syscall(SYS_execve, PathName, argv, envp); end; {$OPTIMIZATION ON} procedure InitExecveRedirect; type PRedirectCodeRec = ^TRedirectCodeRec; TRedirectCodeRec = packed record Code: Byte; // $E9 jmp Distance Distance: Integer; end; const Prot = PROT_READ or PROT_WRITE or PROT_EXEC; Size = SizeOf(TRedirectCodeRec); var Addr: PRedirectCodeRec; AlignedAddr: Cardinal; PageSize: Cardinal; begin PageSize := getpagesize; Addr := dlsym(Pointer(-1), 'execve'); { Obtain write access to the memory page. } AlignedAddr := Cardinal(Addr) and not (PageSize - 1); if Cardinal(Addr) + Size >= AlignedAddr + PageSize then PageSize := PageSize * 2; mprotect(Pointer(AlignedAddr), PageSize, Prot); { Redirect Libc.execve } Addr^.Code := $E9; Addr^.Distance := Integer(@__execve) - Integer(Addr) - Size; end; initialization { Maybe someone has a better code to detect integrated debugging. This code tests only for $DELPHI/$BCB environment variable. } if (getenv('DELPHI') <> nil) or (getenv('BCB') <> nil) then // started within Kylix IDE InitExecveRedirect; {$ENDIF} end.