mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-27 21:10:28 +02:00
* attempt at crt1 translation to get freebsd 12 running.
git-svn-id: trunk@44289 -
This commit is contained in:
parent
db267dcb63
commit
7b4ef925f0
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -10603,6 +10603,7 @@ rtl/freebsd/Makefile.fpc svneol=native#text/plain
|
||||
rtl/freebsd/buildrtl.lpi svneol=native#text/plain
|
||||
rtl/freebsd/buildrtl.pp svneol=native#text/plain
|
||||
rtl/freebsd/console.pp svneol=native#text/plain
|
||||
rtl/freebsd/csucommon/ignore_init.inc svneol=native#text/plain
|
||||
rtl/freebsd/errno.inc svneol=native#text/plain
|
||||
rtl/freebsd/errnostr.inc svneol=native#text/plain
|
||||
rtl/freebsd/freebsd.pas -text svneol=unset#text/plain
|
||||
@ -10638,6 +10639,7 @@ rtl/freebsd/x86_64/cprt0.as svneol=native#text/plain
|
||||
rtl/freebsd/x86_64/dllprt0.as svneol=native#text/plain
|
||||
rtl/freebsd/x86_64/gprt0.as svneol=native#text/plain
|
||||
rtl/freebsd/x86_64/prt0.as svneol=native#text/plain
|
||||
rtl/freebsd/x86_64/reloc.inc svneol=native#text/plain
|
||||
rtl/freebsd/x86_64/si_c.inc svneol=native#text/plain
|
||||
rtl/freebsd/x86_64/sighnd.inc svneol=native#text/plain
|
||||
rtl/gba/Makefile svneol=native#text/plain
|
||||
|
208
rtl/freebsd/csucommon/ignore_init.inc
Normal file
208
rtl/freebsd/csucommon/ignore_init.inc
Normal file
@ -0,0 +1,208 @@
|
||||
{
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright 2012 Konstantin Belousov <kib@FreeBSD.org>
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
*
|
||||
* Parts of this software was developed by Konstantin Belousov
|
||||
* <kib@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Translated into Pascal by Marco van de Voort
|
||||
}
|
||||
|
||||
//#include <sys/cdefs.h>
|
||||
//__FBSDID("$FreeBSD: releng/12.1/lib/csu/common/ignore_init.c 339351 2018-10-13 23:52:55Z kib $");
|
||||
|
||||
//#include <sys/param.h>
|
||||
//#include <sys/elf.h>
|
||||
//#include <sys/elf_common.h>
|
||||
|
||||
//#include "notes.h"
|
||||
|
||||
// replaced by pascalmain in si_c.pp
|
||||
//function cmain(argc:longint;argv:ppchar;env:ppchar):longint; cdecl; external name '_main';
|
||||
|
||||
|
||||
Type TInitProc = procedure(argc:longint;argv:ppchar;env:ppchar); cdecl;
|
||||
PInitProc = ^TInitProc;
|
||||
TCleanupProc = procedure; cdecl;
|
||||
PCleanupProc = ^TCleanupProc;
|
||||
|
||||
procedure atexit(prc:TCleanupProc); cdecl external name 'atexit';
|
||||
procedure cleanup(prc:TCleanupProc); cdecl external name 'cleanup';
|
||||
|
||||
var
|
||||
environ : ppchar; cvar; public name '__environ';
|
||||
_Dynamic : longint; weakexternal name '_DYNAMIC';
|
||||
|
||||
var
|
||||
preinit_array_start : PInitProc; external name '__preinit_array_start';
|
||||
preinit_array_end : PInitProc; external name '__preinit_array_end';
|
||||
init_array_start : PInitProc; external name '__init_array_start';
|
||||
init_array_end : PInitProc; external name '__init_array_end';
|
||||
fini_array_start : PCleanupProc; external name '__fini_array_start';
|
||||
fini_array_end : PCleanupProc; external name '__fini_array_end';
|
||||
|
||||
|
||||
procedure _fini; cdecl; external name '_fini';
|
||||
procedure _init; cdecl; external name '_init';
|
||||
procedure libc_exit(exitcode:longint);cdecl; external name 'exit';
|
||||
|
||||
Type
|
||||
// I only doublechecked these for don't know how these records are defined, but they are resp. 24 and 16 byte on 64-bit
|
||||
Elf_Rela = record
|
||||
r_offset : uint64 {Elf64_Addr}; { Location to be relocated. }
|
||||
r_info : uint64 {Elf64_Xword}; { Relocation type and symbol index. }
|
||||
r_addend : uint64 {Elf64_Sxword}; { Addend. }
|
||||
end;
|
||||
PElf_Rela = ^Elf_Rela;
|
||||
Elf_Rel = record
|
||||
r_offset : uint64 {Elf64_Addr}; { Location to be relocated. }
|
||||
r_info : uint64 {Elf64_Xword}; { Relocation type and symbol index. }
|
||||
end;
|
||||
PElf_Rel = ^Elf_Rel;
|
||||
|
||||
{$if defined(CRT_IRELOC_RELA)}
|
||||
var
|
||||
rela_iplt_start : Elf_rela; weakexternal name '__rela_iplt_start';
|
||||
rela_iplt_end : Elf_rela; weakexternal name '__rela_iplt_end';
|
||||
|
||||
{$include reloc.inc}
|
||||
|
||||
procedure process_irelocs; cdecl;
|
||||
var p,p2 : pElf_Rela;
|
||||
begin
|
||||
p:=@rela_iplt_start;
|
||||
p2:=@rela_iplt_end;
|
||||
while (p<p2) do
|
||||
begin
|
||||
crt1_handle_rela(p);
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
{$elseif defined(CRT_IRELOC_REL)}
|
||||
|
||||
var
|
||||
rel_iplt_start : Elf_Rel; weakexternal name '__rel_iplt_start';
|
||||
rel_iplt_end : Elf_Rel; weakexternal name '__rel_iplt_end';
|
||||
|
||||
{$include reloc.inc}
|
||||
|
||||
procedure process_irelocs; cdecl;
|
||||
var p,p2 : pElf_Rel;
|
||||
begin
|
||||
p:=@rel_iplt_start;
|
||||
p2:=@rel_iplt_end;
|
||||
while (p<p2) do
|
||||
begin
|
||||
crt1_handle_rel(p)
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
|
||||
{$elseif defined(CRT_IRELOC_SUPPRESS)}
|
||||
{$else}
|
||||
{$error 'Define platform reloc type'}
|
||||
{$endif}
|
||||
|
||||
|
||||
procedure finalizer; cdecl;
|
||||
var
|
||||
fn : TCleanupProc;
|
||||
n,array_size : ptruint; // actually: size_t;
|
||||
begin
|
||||
array_size:= fini_array_end - fini_array_start;
|
||||
n:=array_size;
|
||||
while n>0 do
|
||||
begin
|
||||
fn := fini_array_start[n - 1];
|
||||
if assigned(fn) and (ptrint(fn)<>-1) then
|
||||
fn();
|
||||
dec(n);
|
||||
end;
|
||||
_fini();
|
||||
end;
|
||||
|
||||
procedure handle_static_init(argc:longint;argv:ppchar;env:ppchar); cdecl;
|
||||
var fn : TInitProc;
|
||||
n,array_size : ptruint; // actually: size_t;
|
||||
begin
|
||||
if assigned(@_dynamic) then
|
||||
exit;
|
||||
atexit(@finalizer);
|
||||
array_size := preinit_array_end - preinit_array_start;
|
||||
n:=0;
|
||||
while n<array_size do
|
||||
begin
|
||||
fn := preinit_array_start[n];
|
||||
if assigned(fn) and (ptrint(fn)<>-1) then
|
||||
fn(argc,argv,env);
|
||||
inc(n);
|
||||
end;
|
||||
_init();
|
||||
n:=0;
|
||||
while n<array_size do
|
||||
begin
|
||||
fn := init_array_start[n];
|
||||
if assigned(fn) and (ptrint(fn)<>-1) then
|
||||
fn(argc,argv,env);
|
||||
inc(n);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure handle_argv(argc:longint;argv:ppchar;env:ppchar); inline;
|
||||
var
|
||||
s: pchar;
|
||||
begin
|
||||
if assigned(environ) then
|
||||
environ:=env;
|
||||
if (argc>0) and assigned(argv[0]) then
|
||||
begin
|
||||
progname:=argv[0];
|
||||
s:=progname;
|
||||
while s^<>#0 do
|
||||
begin
|
||||
if s^='/' then
|
||||
progname:=@s[1];
|
||||
inc(s);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
(*
|
||||
static const struct {
|
||||
int32_t namesz;
|
||||
int32_t descsz;
|
||||
int32_t type;
|
||||
char name[sizeof(NOTE_FREEBSD_VENDOR)];
|
||||
uint32_t desc;
|
||||
} crt_noinit_tag __attribute__ ((section (NOTE_SECTION),
|
||||
aligned(4))) __used = {
|
||||
.namesz = sizeof(NOTE_FREEBSD_VENDOR),
|
||||
.descsz = sizeof(uint32_t),
|
||||
.type = NT_FREEBSD_NOINIT_TAG,
|
||||
.name = NOTE_FREEBSD_VENDOR,
|
||||
.desc = 0
|
||||
};
|
||||
|
||||
*)
|
@ -21,6 +21,6 @@ interface
|
||||
implementation
|
||||
|
||||
{$i sysnr.inc}
|
||||
{$i si_crt.inc}
|
||||
{$i si_c.inc}
|
||||
|
||||
end.
|
||||
|
@ -5,3 +5,5 @@ var
|
||||
operatingsystem_parameter_envp: ppchar; public name 'operatingsystem_parameter_envp';
|
||||
operatingsystem_parameter_argc: ptruint; public name 'operatingsystem_parameter_argc';
|
||||
operatingsystem_parameter_argv: ppchar; public name 'operatingsystem_parameter_argv';
|
||||
progname: pchar = ''; cvar; public name '__progname';
|
||||
|
||||
|
124
rtl/freebsd/x86_64/reloc.inc
Normal file
124
rtl/freebsd/x86_64/reloc.inc
Normal file
@ -0,0 +1,124 @@
|
||||
{-
|
||||
* Copyright (c) 2018 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
}
|
||||
|
||||
//#include <sys/cdefs.h>
|
||||
//__FBSDID("$FreeBSD: releng/12.1/lib/csu/amd64/reloc.c 339351 2018-10-13 23:52:55Z kib $");
|
||||
|
||||
//#include <machine/specialreg.h>
|
||||
//#include <machine/cpufunc.h>
|
||||
|
||||
Type
|
||||
Elf_Addr = uint64;
|
||||
PElf_Addr = ^Elf_Addr;
|
||||
TElfAddrProc = function (feat1,feat2,stdextfeat1,stdextfeat2:uint32):Elf_Addr; cdecl;
|
||||
|
||||
const R_X86_64_IRELATIVE = 37;
|
||||
|
||||
procedure freebsdIdentTag;nostackframe;assembler;
|
||||
asm
|
||||
.section ".note.openbsd.ident", "a"
|
||||
.p2align 2
|
||||
.long 8
|
||||
.long 4
|
||||
.long 1
|
||||
.asciz "OpenBSD"
|
||||
.long 0
|
||||
|
||||
.text
|
||||
end;
|
||||
|
||||
function ELF_R_TYPE(info:elf_addr):uint32;inline;
|
||||
begin
|
||||
ELF_R_TYPE:=info and uint32($ffffffff);
|
||||
end;
|
||||
|
||||
{$asmmode intel}
|
||||
procedure do_cpuid(funcnr : integer; var p);
|
||||
begin
|
||||
asm
|
||||
mov rax,rdi
|
||||
cpuid
|
||||
mov [rsi],eax
|
||||
mov [rsi+4],ebx
|
||||
mov [rsi+8],ecx
|
||||
mov [rsi+12],edx
|
||||
end['rbx']; // rbx is callee saved in sysv
|
||||
end;
|
||||
|
||||
procedure cpuid_count(funcnr : integer;count:integer;var p);
|
||||
begin
|
||||
asm
|
||||
mov rax,rdi // funcnr
|
||||
mov rcx,rsi // count
|
||||
mov rsi,rdx // save pointer since cpuid destroys edx
|
||||
cpuid
|
||||
mov [rsi],eax
|
||||
mov [rsi+4],ebx
|
||||
mov [rsi+8],ecx
|
||||
mov [rsi+12],edx
|
||||
end['rbx'];
|
||||
end;
|
||||
|
||||
procedure crt1_handle_rela(r : pelf_rela);
|
||||
var p : array[0..3] of uint32;
|
||||
ptr,
|
||||
where : PElf_Addr;
|
||||
target : Elf_Addr;
|
||||
cpu_feature,
|
||||
cpu_feature2 : uint32;
|
||||
cpu_stdext_feature,
|
||||
cpu_stdext_feature2 : uint32;
|
||||
begin
|
||||
do_cpuid(1, p);
|
||||
cpu_feature := p[3];
|
||||
cpu_feature2 := p[2];
|
||||
do_cpuid(0, p);
|
||||
if (p[0] >= 7) then
|
||||
begin
|
||||
cpuid_count(7, 0, p);
|
||||
cpu_stdext_feature := p[1];
|
||||
cpu_stdext_feature2 := p[2];
|
||||
end
|
||||
else
|
||||
begin
|
||||
cpu_stdext_feature := 0;
|
||||
cpu_stdext_feature2 := 0;
|
||||
end;
|
||||
|
||||
case (ELF_R_TYPE(r^.r_info)) of
|
||||
R_X86_64_IRELATIVE:
|
||||
begin
|
||||
ptr := PElf_Addr(r^.r_addend);
|
||||
where := PElf_Addr (r^.r_offset);
|
||||
target := TElfAddrProc(ptr)(cpu_feature, cpu_feature2,
|
||||
cpu_stdext_feature, cpu_stdext_feature2);
|
||||
where^:=target;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -1,30 +1,20 @@
|
||||
|
||||
Type
|
||||
TCleanup = procedure; cdecl;
|
||||
{$define CRT_IRELOC_RELA}
|
||||
|
||||
var
|
||||
environ : ppchar; cvar; public name '__environ';
|
||||
progname: pchar = #0#0; cvar; public name '__progname';
|
||||
dynamic : pchar; external name '_DYNAMIC'; // #pragma weak
|
||||
|
||||
procedure atexit(prc:TCleanup); cdecl external name 'atexit';
|
||||
procedure cleanup(prc:TCleanup); cdecl external name 'cleanup';
|
||||
procedure init_tls; cdecl; external name 'init_tls';
|
||||
procedure fini; cdecl; external name '_fini';
|
||||
procedure init; cdecl; external name '_init';
|
||||
procedure libc_exit(exitcode:longint);cdecl; external name 'exit';
|
||||
function main(nrarg:longint;pp:ppchar;env:ppchar):longint; cdecl; external name 'main';
|
||||
function cmain(nrarg:longint;pp:ppchar;env:ppchar):longint; cdecl; external name 'main';
|
||||
|
||||
{$ifdef gcrt}
|
||||
procedure cmcleanup; cdecl; external name '_mcleanup';
|
||||
procedure monstratup(p,p2:pointer); cdecl; external name 'monstartup';
|
||||
|
||||
var
|
||||
eprol:longint; external name 'eprol';
|
||||
etext:longint; external name 'etext';
|
||||
eprol:longint; external name 'eprol';
|
||||
etext:longint; external name 'etext';
|
||||
{$endif}
|
||||
|
||||
procedure start(ap:ppchar;cleanup:TCleanup);
|
||||
{$i ignore_init.inc}
|
||||
procedure start(ap:ppchar;cleanup:TCleanupProc);
|
||||
|
||||
var argc: longint;
|
||||
argv: ppchar;
|
||||
@ -35,55 +25,32 @@ begin
|
||||
argv:=ppchar(ap[1]);
|
||||
env:= ppchar(ap[2+argc]);
|
||||
environ:=env;
|
||||
if (argc>0) and (argv[0]<>#0) Then
|
||||
begin
|
||||
progname:=argv[0];
|
||||
s:=progname;
|
||||
while s^<>#0 do
|
||||
begin
|
||||
if s^='/' then
|
||||
progname:=@s[1];
|
||||
inc(s);
|
||||
end;
|
||||
end;
|
||||
if assigned(pchar(@dynamic)) then // I suspect this is a trick to find
|
||||
handle_argv(argc,argv,env);
|
||||
if assigned(pchar(@_dynamic)) then // I suspect this is a trick to find
|
||||
// out runtime if we are shared
|
||||
// linking, so the same code can be used
|
||||
// for static and shared linking
|
||||
atexit(cleanup)
|
||||
else
|
||||
init_tls;
|
||||
begin
|
||||
process_irelocs();
|
||||
init_tls;
|
||||
end;
|
||||
|
||||
{$ifdef GCRT}
|
||||
atexit(@_mcleanup);
|
||||
atexit(@cmcleanup);
|
||||
{$endif}
|
||||
atexit(@fini);
|
||||
atexit(@_fini);
|
||||
{$ifdef GCRT}
|
||||
monstartup(@eprol,@etext);
|
||||
asm
|
||||
eprol:
|
||||
end;
|
||||
{$endif}
|
||||
init;
|
||||
libc_exit(main(argc,argv,env)); // doesn't return
|
||||
asm
|
||||
{ We need this stuff to make gdb behave itself, otherwise
|
||||
gdb will chokes with SIGILL when trying to debug apps.
|
||||
}
|
||||
.section ".note.ABI-tag", "a"
|
||||
.align 4
|
||||
.long 8
|
||||
.long 4
|
||||
.long 1
|
||||
.asciz "FreeBSD"
|
||||
.align 4
|
||||
.long 900044
|
||||
.align 4
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
end;
|
||||
handle_static_init(argc, argv, env);
|
||||
libc_exit(cmain(argc,argv,env)); // doesn't return
|
||||
end;
|
||||
|
||||
|
||||
|
||||
begin
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user