* attempt at crt1 translation to get freebsd 12 running.

git-svn-id: trunk@44289 -
This commit is contained in:
marco 2020-03-08 16:37:30 +00:00
parent db267dcb63
commit 7b4ef925f0
6 changed files with 354 additions and 51 deletions

2
.gitattributes vendored
View File

@ -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

View 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
};
*)

View File

@ -21,6 +21,6 @@ interface
implementation
{$i sysnr.inc}
{$i si_crt.inc}
{$i si_c.inc}
end.

View File

@ -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';

View 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;

View File

@ -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.