mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-15 02:54:07 +08:00
95 lines
3.5 KiB
ObjectPascal
95 lines
3.5 KiB
ObjectPascal
{********************************************************************
|
|
* 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.
|
|
|