Merge pull request #227914 from emilytrau/trusting-trust

stdenv: begin work on 256b bootstrap i.e. Trusting Trust
This commit is contained in:
John Ericson 2023-05-09 16:14:41 -04:00 committed by GitHub
commit 47d50c9586
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1772 additions and 0 deletions

View file

@ -0,0 +1,24 @@
{ lib
, config
, buildPlatform
, hostPlatform
}:
lib.makeScope
# Prevent using top-level attrs to protect against introducing dependency on
# non-bootstrap packages by mistake. Any top-level inputs must be explicitly
# declared here.
(extra: lib.callPackageWith ({ inherit lib config buildPlatform hostPlatform; } // extra))
(self: with self; {
inherit (callPackage ./utils.nix { }) fetchurl derivationWithMeta writeTextFile writeText runCommand;
inherit (callPackage ./stage0-posix { }) kaem m2libc mescc-tools mescc-tools-extra;
mes = callPackage ./mes { };
mes-libc = callPackage ./mes/libc.nix { };
ln-boot = callPackage ./ln-boot { };
tinycc-bootstrappable = callPackage ./tinycc/bootstrappable.nix { };
tinycc-mes = callPackage ./tinycc/mes.nix { };
})

View file

@ -0,0 +1,27 @@
{ lib
, runCommand
, mes
}:
let
pname = "ln-boot";
version = "unstable-2023-05-01";
src = ./ln.c;
in
runCommand "${pname}-${version}" {
inherit pname version;
meta = with lib; {
description = "Basic tool for creating symbolic links";
license = licenses.mit;
maintainers = with maintainers; [ emilytrau ];
mainProgram = "ln";
platforms = platforms.unix;
};
} ''
mkdir -p ''${out}/bin
${mes}/bin/mes --no-auto-compile -e main ${mes}/bin/mescc.scm -- \
-lc+tcc \
-o ''${out}/bin/ln \
${src}
''

View file

@ -0,0 +1,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char** argv)
{
if (argc != 4 || strcmp(argv[1], "-s")) {
fputs("Usage: ", stdout);
fputs(argv[0], stdout);
fputs("ln -s TARGET LINK_NAME\n", stdout);
exit(EXIT_FAILURE);
}
symlink(argv[2], argv[3]);
exit(EXIT_SUCCESS);
}

View file

@ -0,0 +1,189 @@
{ lib
, runCommand
, fetchurl
, writeText
, callPackage
, m2libc
, mescc-tools
}:
let
pname = "mes";
version = "0.24.2";
src = fetchurl {
url = "mirror://gnu/mes/mes-${version}.tar.gz";
sha256 = "0vp8v88zszh1imm3dvdfi3m8cywshdj7xcrsq4cgmss69s2y1nkx";
};
nyacc = callPackage ./nyacc.nix { inherit nyacc; };
config_h = builtins.toFile "config.h" ''
#undef SYSTEM_LIBC
#define MES_VERSION "${version}"
'';
sources = (import ./sources.nix).x86.linux.mescc;
inherit (sources) libc_mini_SOURCES libmescc_SOURCES libc_SOURCES mes_SOURCES;
# add symlink() to libc+tcc so we can use it in ln-boot
libc_tcc_SOURCES = sources.libc_tcc_SOURCES ++ [ "lib/linux/symlink.c" ];
compile = sources:
lib.concatMapStringsSep
"\n"
(f: ''CC -c ''${MES_PREFIX}/${f}'')
sources;
replaceExt = ext: source:
lib.replaceStrings
[ ".c" ]
[ ext ]
(builtins.baseNameOf source);
archive = out: sources:
"catm ${out} ${lib.concatMapStringsSep " " (replaceExt ".o") sources}";
sourceArchive = out: sources:
"catm ${out} ${lib.concatMapStringsSep " " (replaceExt ".s") sources}";
in
runCommand "${pname}-${version}" {
inherit pname version;
passthru = { inherit src nyacc; };
meta = with lib; {
description = "Scheme interpreter and C compiler for bootstrapping";
homepage = "https://www.gnu.org/software/mes";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
}
# Maintenance note:
# Build steps have been adapted from build-aux/bootstrap.sh.in
# as well as the live-bootstrap project
# https://github.com/fosslinux/live-bootstrap/blob/1bc4296091c51f53a5598050c8956d16e945b0f5/sysa/mes-0.24.2/mes-0.24.2.kaem
''
# Unpack source
ungz --file ${src} --output mes.tar
mkdir ''${out} ''${out}/bin ''${out}/share
cd ''${out}/share
untar --non-strict --file ''${NIX_BUILD_TOP}/mes.tar # ignore symlinks
MES_PREFIX=''${out}/share/mes-${version}
LIBDIR=''${MES_PREFIX}/lib
cd ''${MES_PREFIX}
cp ${config_h} include/mes/config.h
mkdir include/arch
cp include/linux/x86/syscall.h include/arch/syscall.h
cp include/linux/x86/kernel-stat.h include/arch/kernel-stat.h
# Remove pregenerated files
rm mes/module/mes/psyntax.pp mes/module/mes/psyntax.pp.header
# These files are symlinked in the repo
cp mes/module/srfi/srfi-9-struct.mes mes/module/srfi/srfi-9.mes
cp mes/module/srfi/srfi-9/gnu-struct.mes mes/module/srfi/srfi-9/gnu.mes
# Fixes to support newer M2-Planet
catm x86_defs.M1 ${m2libc}/x86/x86_defs.M1 lib/m2/x86/x86_defs.M1
cp x86_defs.M1 lib/m2/x86/x86_defs.M1
rm x86_defs.M1
# Remove environment impurities
__GUILE_LOAD_PATH="\"''${MES_PREFIX}/mes/module:''${MES_PREFIX}/module:${nyacc.guilePath}\""
boot0_scm=mes/module/mes/boot-0.scm
guile_mes=mes/module/mes/guile.mes
replace --file ''${boot0_scm} --output ''${boot0_scm} --match-on "(getenv \"GUILE_LOAD_PATH\")" --replace-with ''${__GUILE_LOAD_PATH}
replace --file ''${guile_mes} --output ''${guile_mes} --match-on "(getenv \"GUILE_LOAD_PATH\")" --replace-with ''${__GUILE_LOAD_PATH}
module_mescc_scm=module/mescc/mescc.scm
replace --file ''${module_mescc_scm} --output ''${module_mescc_scm} --match-on "(getenv \"M1\")" --replace-with "\"${mescc-tools}/bin/M1\""
replace --file ''${module_mescc_scm} --output ''${module_mescc_scm} --match-on "(getenv \"HEX2\")" --replace-with "\"${mescc-tools}/bin/hex2\""
replace --file ''${module_mescc_scm} --output ''${module_mescc_scm} --match-on "(getenv \"BLOOD_ELF\")" --replace-with "\"${mescc-tools}/bin/blood-elf\""
replace --file ''${module_mescc_scm} --output ''${module_mescc_scm} --match-on "(getenv \"srcdest\")" --replace-with "\"''${MES_PREFIX}\""
mes_c=src/mes.c
replace --file ''${mes_c} --output ''${mes_c} --match-on "getenv (\"MES_PREFIX\")" --replace-with "\"''${MES_PREFIX}\""
replace --file ''${mes_c} --output ''${mes_c} --match-on "getenv (\"srcdest\")" --replace-with "\"''${MES_PREFIX}\""
# Increase runtime resource limits
gc_c=src/gc.c
replace --file ''${gc_c} --output ''${gc_c} --match-on "getenv (\"MES_ARENA\")" --replace-with "\"100000000\""
replace --file ''${gc_c} --output ''${gc_c} --match-on "getenv (\"MES_MAX_ARENA\")" --replace-with "\"100000000\""
replace --file ''${gc_c} --output ''${gc_c} --match-on "getenv (\"MES_STACK\")" --replace-with "\"6000000\""
# Create mescc.scm
mescc_in=scripts/mescc.scm.in
replace --file ''${mescc_in} --output ''${mescc_in} --match-on "(getenv \"MES_PREFIX\")" --replace-with "\"''${MES_PREFIX}\""
replace --file ''${mescc_in} --output ''${mescc_in} --match-on "(getenv \"includedir\")" --replace-with "\"''${MES_PREFIX}/include\""
replace --file ''${mescc_in} --output ''${mescc_in} --match-on "(getenv \"libdir\")" --replace-with "\"''${MES_PREFIX}/lib\""
replace --file ''${mescc_in} --output ''${mescc_in} --match-on @prefix@ --replace-with ''${MES_PREFIX}
replace --file ''${mescc_in} --output ''${mescc_in} --match-on @VERSION@ --replace-with ${version}
replace --file ''${mescc_in} --output ''${mescc_in} --match-on @mes_cpu@ --replace-with x86
replace --file ''${mescc_in} --output ''${mescc_in} --match-on @mes_kernel@ --replace-with linux
cp ''${mescc_in} ''${out}/bin/mescc.scm
# Build mes-m2
mes_cpu=x86
stage0_cpu=x86
kaem --verbose --strict --file kaem.run
cp bin/mes-m2 ''${out}/bin/mes-m2
chmod 555 ''${out}/bin/mes-m2
# Recompile Mes and Mes C library using mes-m2 bootstrapped Mes
cd ''${NIX_BUILD_TOP}
alias CC="''${out}/bin/mes-m2 -e main ''${out}/bin/mescc.scm -- -D HAVE_CONFIG_H=1 -I ''${MES_PREFIX}/include -I ''${MES_PREFIX}/include/linux/x86"
mkdir -p ''${LIBDIR}/x86-mes
# crt1.o
CC -c ''${MES_PREFIX}/lib/linux/x86-mes-mescc/crt1.c
cp crt1.o ''${LIBDIR}/x86-mes
cp crt1.s ''${LIBDIR}/x86-mes
# libc-mini.a
${compile libc_mini_SOURCES}
${archive "libc-mini.a" libc_mini_SOURCES}
${sourceArchive "libc-mini.s" libc_mini_SOURCES}
cp libc-mini.a ''${LIBDIR}/x86-mes
cp libc-mini.s ''${LIBDIR}/x86-mes
# libmescc.a
${compile libmescc_SOURCES}
${archive "libmescc.a" libmescc_SOURCES}
${sourceArchive "libmescc.s" libmescc_SOURCES}
cp libmescc.a ''${LIBDIR}/x86-mes
cp libmescc.s ''${LIBDIR}/x86-mes
# libc.a
${compile libc_SOURCES}
${archive "libc.a" libc_SOURCES}
${sourceArchive "libc.s" libc_SOURCES}
cp libc.a ''${LIBDIR}/x86-mes
cp libc.s ''${LIBDIR}/x86-mes
# libc+tcc.a
# optimisation: don't recompile common libc sources
${compile (lib.subtractLists libc_SOURCES libc_tcc_SOURCES)}
${archive "libc+tcc.a" libc_tcc_SOURCES}
${sourceArchive "libc+tcc.s" libc_tcc_SOURCES}
cp libc+tcc.a ''${LIBDIR}/x86-mes
cp libc+tcc.s ''${LIBDIR}/x86-mes
# Build mes itself
${compile mes_SOURCES}
''${out}/bin/mes-m2 -e main ''${out}/bin/mescc.scm -- \
--base-address 0x08048000 \
-L ''${MES_PREFIX}/lib \
-L . \
-lc \
-lmescc \
-nostdlib \
-o ''${out}/bin/mes \
crt1.o \
${lib.concatMapStringsSep " " (replaceExt ".o") mes_SOURCES}
# Check
''${out}/bin/mes --version
''

View file

@ -0,0 +1,95 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p bash coreutils gnutar
# Generate a sources.nix for a version of GNU mes. Creates lists of source files
# from build-aux/configure-lib.sh.
#
# You may point this tool at a manually downloaded tarball, but more ideal is
# using the source tarball from Nixpkgs. For example:
#
# MES_TARBALL="$(nix-build --no-link -A minimal-bootstrap.mes.src ../../../../..)"
# ./gen-sources.sh "$MES_TARBALL" > ./new-sources.nix
set -eu
# Supported platforms
ARCHS="x86"
KERNELS="linux"
COMPILERS="mescc gcc"
format() {
echo -n "[ "
# Terrible hack to convert a newline-delimited string to space-delimited
echo $* | xargs printf '"%s" '
echo -n "]"
}
gen_sources() {
# Configuration variables used by configure-lib.sh
export mes_libc=mes
export mes_cpu=$1
export mes_kernel=$2
export compiler=$3
# Populate source file lists
source $CONFIGURE_LIB_SH
cat <<EOF
$mes_cpu.$mes_kernel.$compiler = {
libc_mini_SOURCES = $(format $libc_mini_SOURCES);
libmescc_SOURCES = $(format $libmescc_SOURCES);
libtcc1_SOURCES = $(format $libtcc1_SOURCES);
libc_SOURCES = $(format $libc_SOURCES);
libc_tcc_SOURCES = $(format $libc_tcc_SOURCES);
libc_gnu_SOURCES = $(format $libc_gnu_SOURCES);
mes_SOURCES = $(format $mes_SOURCES);
};
EOF
}
MES_TARBALL=$1
if [ ! -f $MES_TARBALL ]; then
echo "Provide path to mes-x.x.x.tar.gz as first argument" >&2
exit 1
fi
echo "Generating sources.nix from $MES_TARBALL" >&2
TMP=$(mktemp -d)
cd $TMP
echo "Workdir: $TMP" >&2
echo "Extracting $MES_TARBALL" >&2
tar --strip-components 1 -xf $MES_TARBALL
CONFIGURE_LIB_SH="$TMP/build-aux/configure-lib.sh"
if [ ! -f $CONFIGURE_LIB_SH ]; then
echo "Could not find mes's configure-lib.sh script at $CONFIGURE_LIB_SH" >&2
exit 1
fi
# Create dummy config expected by configure-lib.sh
touch config.sh
chmod +x config.sh
echo "Configuring with $CONFIGURE_LIB_SH" >&2
cat <<EOF
# This file is generated by ./gen-sources.sh.
# Do not edit!
{
EOF
for arch in $ARCHS; do
for kernel in $KERNELS; do
for compiler in $COMPILERS; do
gen_sources $arch $kernel $compiler
done
done
done
cat <<EOF
}
EOF

View file

@ -0,0 +1,62 @@
{ lib
, runCommand
, ln-boot
, mes
, mes-libc
}:
let
pname = "mes-libc";
inherit (mes) version;
sources = (import ./sources.nix).x86.linux.gcc;
inherit (sources) libtcc1_SOURCES libc_gnu_SOURCES;
prefix = "${mes}/share/mes-${version}";
# Concatenate all source files into a convenient bundle
# "gcc" variants of source files (eg. "lib/linux/x86-mes-gcc") can also be
# compiled by tinycc
#
# Passing this many arguments is too much for kaem so we need to split
# the operation in two
firstLibc = lib.take 100 libc_gnu_SOURCES;
lastLibc = lib.drop 100 libc_gnu_SOURCES;
in runCommand "${pname}-${version}" {
inherit pname version;
nativeBuildInputs = [ ln-boot ];
passthru.CFLAGS = "-DHAVE_CONFIG_H=1 -I${mes-libc}/include -I${mes-libc}/include/linux/x86";
meta = with lib; {
description = "The Mes C Library";
homepage = "https://www.gnu.org/software/mes";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
} ''
cd ${prefix}
# mescc compiled libc.a
mkdir -p ''${out}/lib/x86-mes
cp lib/x86-mes/libc.a ''${out}/lib/x86-mes
# libc.c
catm ''${TMPDIR}/first.c ${lib.concatStringsSep " " firstLibc}
catm ''${out}/lib/libc.c ''${TMPDIR}/first.c ${lib.concatStringsSep " " lastLibc}
# crt{1,n,i}.c
cp lib/linux/x86-mes-gcc/crt1.c ''${out}/lib
cp lib/linux/x86-mes-gcc/crtn.c ''${out}/lib
cp lib/linux/x86-mes-gcc/crti.c ''${out}/lib
# libtcc1.c
catm ''${out}/lib/libtcc1.c ${lib.concatStringsSep " " libtcc1_SOURCES}
# getopt.c
cp lib/posix/getopt.c ''${out}/lib/libgetopt.c
# Install headers
ln -s ${prefix}/include ''${out}/include
''

View file

@ -0,0 +1,39 @@
{ lib
, runCommand
, fetchurl
, nyacc
}:
let
pname = "nyacc";
# NYACC is a tightly coupled dependency of mes. This version is known to work
# with mes 0.24.2.
# https://git.savannah.gnu.org/cgit/mes.git/tree/INSTALL?h=v0.24.2&id=7562330ec746f09b4060d3081e3377fb7083897d#n31
version = "1.00.2";
src = fetchurl {
url = "mirror://savannah/nyacc/nyacc-${version}.tar.gz";
sha256 = "065ksalfllbdrzl12dz9d9dcxrv97wqxblslngsc6kajvnvlyvpk";
};
in
runCommand "${pname}-${version}" {
inherit pname version;
passthru.guilePath = "${nyacc}/share/${pname}-${version}/module";
meta = with lib; {
description = "Modules for generating parsers and lexical analyzers";
longDescription = ''
Not Yet Another Compiler Compiler is a set of guile modules for
generating computer language parsers and lexical analyzers.
'';
homepage = "https://savannah.nongnu.org/projects/nyacc";
license = licenses.lgpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = platforms.all;
};
} ''
ungz --file ${src} --output nyacc.tar
mkdir -p ''${out}/share
cd ''${out}/share
untar --file ''${NIX_BUILD_TOP}/nyacc.tar
''

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,34 @@
rec {
name = "stage0-posix-${version}-${rev}-source";
# Pinned from https://github.com/oriansj/stage0-posix/commit/3189b5f325b7ef8b88e3edec7c1cde4fce73c76c
version = "unstable-2023-05-02";
rev = "3189b5f325b7ef8b88e3edec7c1cde4fce73c76c";
# This 256 byte seed is the only pre-compiled binary in the bootstrap chain.
# While it is included in the stage0-posix source bundle and is synced with
# stage0-posix updates, we have split it out into its own derivation to highlight
# its unique status as a trusted binary seed.
hex0-seed = import <nix/fetchurl.nix> {
name = "hex0-seed-${version}";
url = "https://github.com/oriansj/bootstrap-seeds/raw/b1263ff14a17835f4d12539226208c426ced4fba/POSIX/x86/hex0-seed";
hash = "sha256-QU3RPGy51W7M2xnfFY1IqruKzusrSLU+L190ztN6JW8=";
executable = true;
};
# Packaged resources required for the first bootstrapping stage.
# Contains source code and 256-byte hex0 binary seed.
#
# We don't have access to utilities such as fetchgit and fetchzip since this
# is this is part of the bootstrap process and would introduce a circular
# dependency. The only tool we have to fetch source trees is `import <nix/fetchurl.nix>`
# with the unpack option, taking a NAR file as input. This requires source
# tarballs to be repackaged.
#
# To build see `make-bootstrap-sources.nix`
src = import <nix/fetchurl.nix> {
inherit name;
url = "https://github.com/emilytrau/bootstrap-tools-nar-mirror/releases/download/2023-05-02/${name}.nar.xz";
hash = "sha256-ZRG0k49MxL1UTZhuMTvPoEprdSpJRNVy8QhLE6k+etg=";
unpack = true;
};
}

View file

@ -0,0 +1,20 @@
{ lib
, newScope
}:
lib.makeScope newScope (self: with self; {
inherit (import ./bootstrap-sources.nix) version hex0-seed src;
m2libc = src + "/M2libc";
hex0 = callPackage ./hex0.nix { };
kaem = callPackage ./kaem { };
kaem-minimal = callPackage ./kaem/minimal.nix { };
inherit (callPackage ./stage0-posix-x86.nix { }) blood-elf-0 hex2 kaem-unwrapped M1 M2;
mescc-tools = callPackage ./mescc-tools { };
mescc-tools-extra = callPackage ./mescc-tools-extra { };
})

View file

@ -0,0 +1,28 @@
{ lib
, derivationWithMeta
, hex0-seed
, src
, version
}:
derivationWithMeta {
inherit version;
pname = "hex0";
builder = hex0-seed;
args = [
"${src}/bootstrap-seeds/POSIX/x86/hex0_x86.hex0"
(placeholder "out")
];
meta = with lib; {
description = "Minimal assembler for bootstrapping";
homepage = "https://github.com/oriansj/stage0-posix";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
# Ensure the untrusted hex0-seed binary produces a known-good hex0
outputHashMode = "recursive";
outputHashAlgo = "sha256";
outputHash = "sha256-QU3RPGy51W7M2xnfFY1IqruKzusrSLU+L190ztN6JW8=";
}

View file

@ -0,0 +1,33 @@
{ lib
, derivationWithMeta
, kaem-unwrapped
, mescc-tools-extra
, version
}:
# Once mescc-tools-extra is available we can install kaem at /bin/kaem
# to make it findable in environments
derivationWithMeta {
inherit version kaem-unwrapped;
pname = "kaem";
builder = kaem-unwrapped;
args = [
"--verbose"
"--strict"
"--file"
(builtins.toFile "kaem-wrapper.kaem" ''
mkdir -p ''${out}/bin
cp ''${kaem-unwrapped} ''${out}/bin/kaem
chmod 555 ''${out}/bin/kaem
'')
];
PATH = lib.makeBinPath [ mescc-tools-extra ];
meta = with lib; {
description = "Minimal build tool for running scripts on systems that lack any shell";
homepage = "https://github.com/oriansj/mescc-tools";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
}

View file

@ -0,0 +1,24 @@
{ lib
, derivationWithMeta
, src
, hex0
, version
}:
derivationWithMeta {
inherit version;
pname = "kaem-minimal";
builder = hex0;
args = [
"${src}/bootstrap-seeds/POSIX/x86/kaem-minimal.hex0"
(placeholder "out")
];
meta = with lib; {
description = "First stage minimal scriptable build tool for bootstrapping";
homepage = "https://github.com/oriansj/stage0-posix";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
}

View file

@ -0,0 +1,46 @@
# Packaged resources required for the first bootstrapping stage.
# Contains source code and 256-byte hex0 binary seed.
#
# We don't have access to utilities such as fetchgit and fetchzip since this
# is this is part of the bootstrap process and would introduce a circular
# dependency. The only tool we have to fetch source trees is `import <nix/fetchurl.nix>`
# with the unpack option, taking a NAR file as input. This requires source
# tarballs to be repackaged.
#
# To build:
#
# nix-build pkgs/os-specific/linux/minimal-bootstrap/stage0-posix/make-bootstrap-sources.nix
# => ./result/stage0-posix-$version-$rev-source.nar.xz
#
{ pkgs ? import ../../../../.. {} }:
let
inherit (pkgs) callPackage runCommand fetchFromGitHub nix xz;
inherit (import ./bootstrap-sources.nix) name rev;
src = fetchFromGitHub {
owner = "oriansj";
repo = "stage0-posix";
inherit rev;
sha256 = "sha256-ZRG0k49MxL1UTZhuMTvPoEprdSpJRNVy8QhLE6k+etg=";
fetchSubmodules = true;
postFetch = ''
# Remove vendored/duplicate M2libc's
echo "Removing duplicate M2libc"
rm -rf \
$out/M2-Mesoplanet/M2libc \
$out/M2-Planet/M2libc \
$out/mescc-tools/M2libc \
$out/mescc-tools-extra/M2libc
'';
};
in
runCommand name {
nativeBuildInputs = [ nix xz ];
passthru = { inherit src; };
} ''
mkdir $out
nix-store --dump ${src} | xz -c > "$out/${name}.nar.xz"
''

View file

@ -0,0 +1,39 @@
# This is a modified version of mescc-tools-extra/mescc-tools-extra.kaem
# https://github.com/oriansj/mescc-tools-extra/blob/ec53af69d6d2119b47b369cd0ec37ac806e7ad60/mescc-tools-extra.kaem
# - Paths to build inputs have been changed for nix
# - Added additional step to create $out directory
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see <http://www.gnu.org/licenses/>.
alias CC="${mescc-tools}/bin/M2-Mesoplanet --operating-system ${OPERATING_SYSTEM} --architecture ${ARCH} -f"
cd ${src}/mescc-tools-extra
# Create output folder
CC mkdir.c -o ${TMP}/mkdir
${TMP}/mkdir -p ${out}/bin
CC sha256sum.c -o ${out}/bin/sha256sum
CC match.c -o ${out}/bin/match
CC mkdir.c -o ${out}/bin/mkdir
CC untar.c -o ${out}/bin/untar
CC ungz.c -o ${out}/bin/ungz
CC unbz2.c -o ${out}/bin/unbz2
CC catm.c -o ${out}/bin/catm
CC cp.c -o ${out}/bin/cp
CC chmod.c -o ${out}/bin/chmod
CC rm.c -o ${out}/bin/rm
CC replace.c -o ${out}/bin/replace

View file

@ -0,0 +1,29 @@
{ lib
, derivationWithMeta
, kaem-unwrapped
, mescc-tools
, src
, version
}:
derivationWithMeta {
inherit version src mescc-tools;
pname = "mescc-tools-extra";
builder = kaem-unwrapped;
args = [
"--verbose"
"--strict"
"--file"
./build.kaem
];
ARCH = "x86";
OPERATING_SYSTEM = "linux";
meta = with lib; {
description = "Collection of tools written for use in bootstrapping";
homepage = "https://github.com/oriansj/mescc-tools-extra";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
}

View file

@ -0,0 +1,204 @@
# This is a modified version of stage0-posix/x86/mescc-tools-full-kaem.kaem
# https://github.com/oriansj/stage0-posix-x86/blob/56e6b8df3e95f4bc04f8b420a4cd8c82c70b9efa/mescc-tools-full-kaem.kaem
# - Paths to build inputs have been changed for nix
# Mes --- Maxwell Equations of Software
# Copyright © 2017,2019 Jan Nieuwenhuizen <janneke@gnu.org>
# Copyright © 2017,2019 Jeremiah Orians
#
# This file is part of Mes.
#
# Mes is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# Mes is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mes. If not, see <http://www.gnu.org/licenses/>.
${mkdir} -p ${out}/bin
${cp} ${M2} ${out}/bin/M2
${chmod} 0555 ${out}/bin/M2
${cp} ${M1} ${out}/bin/M1
${chmod} 0555 ${out}/bin/M1
${cp} ${hex2} ${out}/bin/hex2
${chmod} 0555 ${out}/bin/hex2
# M2-Mesoplanet searches for runtime dependencies in environment variables
# We can hardcode them with the "replace" utility from mescc-tools-extra
${replace} \
--file ${src}/M2-Mesoplanet/cc.c \
--output ./cc_patched.c \
--match-on "env_lookup(\"M2LIBC_PATH\")" \
--replace-with "\"${m2libc}\""
${replace} \
--file ${src}/M2-Mesoplanet/cc_spawn.c \
--output ./cc_spawn_patched.c \
--match-on "env_lookup(\"PATH\")" \
--replace-with "\"${out}/bin:\""
###############################################
# Phase-12 Build M2-Mesoplanet from M2-Planet #
###############################################
${M2} --architecture ${ARCH} \
-f ${m2libc}/sys/types.h \
-f ${m2libc}/stddef.h \
-f ${m2libc}/${ARCH}/linux/fcntl.c \
-f ${m2libc}/fcntl.c \
-f ${m2libc}/${ARCH}/linux/unistd.c \
-f ${m2libc}/${ARCH}/linux/sys/stat.c \
-f ${m2libc}/stdlib.c \
-f ${m2libc}/stdio.h \
-f ${m2libc}/stdio.c \
-f ${m2libc}/string.c \
-f ${m2libc}/bootstrappable.c \
-f ${src}/M2-Mesoplanet/cc.h \
-f ${src}/M2-Mesoplanet/cc_globals.c \
-f ${src}/M2-Mesoplanet/cc_env.c \
-f ${src}/M2-Mesoplanet/cc_reader.c \
-f ./cc_spawn_patched.c \
-f ${src}/M2-Mesoplanet/cc_core.c \
-f ${src}/M2-Mesoplanet/cc_macro.c \
-f ./cc_patched.c \
--debug \
-o ./M2-Mesoplanet-1.M1
${blood-elf-0} ${ENDIAN_FLAG} ${BLOOD_FLAG} -f ./M2-Mesoplanet-1.M1 -o ./M2-Mesoplanet-1-footer.M1
${M1} --architecture ${ARCH} \
${ENDIAN_FLAG} \
-f ${m2libc}/${ARCH}/${ARCH}_defs.M1 \
-f ${m2libc}/${ARCH}/libc-full.M1 \
-f ./M2-Mesoplanet-1.M1 \
-f ./M2-Mesoplanet-1-footer.M1 \
-o ./M2-Mesoplanet-1.hex2
${hex2} --architecture ${ARCH} \
${ENDIAN_FLAG} \
--base-address ${BASE_ADDRESS} \
-f ${m2libc}/${ARCH}/ELF-${ARCH}-debug.hex2 \
-f ./M2-Mesoplanet-1.hex2 \
-o ${out}/bin/M2-Mesoplanet
#################################################
# Phase-13 Build final blood-elf from C sources #
#################################################
${M2} --architecture ${ARCH} \
-f ${m2libc}/sys/types.h \
-f ${m2libc}/stddef.h \
-f ${m2libc}/${ARCH}/linux/fcntl.c \
-f ${m2libc}/fcntl.c \
-f ${m2libc}/${ARCH}/linux/unistd.c \
-f ${m2libc}/stdlib.c \
-f ${m2libc}/stdio.h \
-f ${m2libc}/stdio.c \
-f ${m2libc}/bootstrappable.c \
-f ${src}/mescc-tools/stringify.c \
-f ${src}/mescc-tools/blood-elf.c \
--debug \
-o ./blood-elf-1.M1
${blood-elf-0} ${BLOOD_FLAG} ${ENDIAN_FLAG} -f ./blood-elf-1.M1 -o ./blood-elf-1-footer.M1
${M1} --architecture ${ARCH} \
${ENDIAN_FLAG} \
-f ${m2libc}/${ARCH}/${ARCH}_defs.M1 \
-f ${m2libc}/${ARCH}/libc-full.M1 \
-f ./blood-elf-1.M1 \
-f ./blood-elf-1-footer.M1 \
-o ./blood-elf-1.hex2
${hex2} --architecture ${ARCH} \
${ENDIAN_FLAG} \
--base-address ${BASE_ADDRESS} \
-f ${m2libc}/${ARCH}/ELF-${ARCH}-debug.hex2 \
-f ./blood-elf-1.hex2 \
-o ${out}/bin/blood-elf
# Now we have our shipping debuggable blood-elf, the rest will be down hill from
# here as we have ALL of the core pieces of compiling and assembling debuggable
# programs in a debuggable form with corresponding C source code.
#############################################
# Phase-14 Build get_machine from C sources #
#############################################
${M2} --architecture ${ARCH} \
-f ${m2libc}/sys/types.h \
-f ${m2libc}/stddef.h \
-f ${m2libc}/${ARCH}/linux/unistd.c \
-f ${m2libc}/${ARCH}/linux/fcntl.c \
-f ${m2libc}/fcntl.c \
-f ${m2libc}/stdlib.c \
-f ${m2libc}/stdio.h \
-f ${m2libc}/stdio.c \
-f ${m2libc}/bootstrappable.c \
-f ${src}/mescc-tools/get_machine.c \
--debug \
-o get_machine.M1
${out}/bin/blood-elf ${BLOOD_FLAG} ${ENDIAN_FLAG} -f ./get_machine.M1 -o ./get_machine-footer.M1
${M1} --architecture ${ARCH} \
${ENDIAN_FLAG} \
-f ${m2libc}/${ARCH}/${ARCH}_defs.M1 \
-f ${m2libc}/${ARCH}/libc-full.M1 \
-f ./get_machine.M1 \
-f ./get_machine-footer.M1 \
-o ./get_machine.hex2
${hex2} --architecture ${ARCH} \
${ENDIAN_FLAG} \
--base-address ${BASE_ADDRESS} \
-f ${m2libc}/${ARCH}/ELF-${ARCH}-debug.hex2 \
-f ./get_machine.hex2 \
-o ${out}/bin/get_machine
############################################
# Phase-15 Build M2-Planet from M2-Planet #
############################################
${M2} --architecture ${ARCH} \
-f ${m2libc}/sys/types.h \
-f ${m2libc}/stddef.h \
-f ${m2libc}/${ARCH}/linux/unistd.c \
-f ${m2libc}/${ARCH}/linux/fcntl.c \
-f ${m2libc}/fcntl.c \
-f ${m2libc}/stdlib.c \
-f ${m2libc}/stdio.h \
-f ${m2libc}/stdio.c \
-f ${m2libc}/bootstrappable.c \
-f ${src}/M2-Planet/cc.h \
-f ${src}/M2-Planet/cc_globals.c \
-f ${src}/M2-Planet/cc_reader.c \
-f ${src}/M2-Planet/cc_strings.c \
-f ${src}/M2-Planet/cc_types.c \
-f ${src}/M2-Planet/cc_core.c \
-f ${src}/M2-Planet/cc_macro.c \
-f ${src}/M2-Planet/cc.c \
--debug \
-o ./M2-1.M1
${out}/bin/blood-elf ${ENDIAN_FLAG} ${BLOOD_FLAG} -f ./M2-1.M1 -o ./M2-1-footer.M1
${M1} --architecture ${ARCH} \
${ENDIAN_FLAG} \
-f ${m2libc}/${ARCH}/${ARCH}_defs.M1 \
-f ${m2libc}/${ARCH}/libc-full.M1 \
-f ./M2-1.M1 \
-f ./M2-1-footer.M1 \
-o ./M2-1.hex2
${hex2} --architecture ${ARCH} \
${ENDIAN_FLAG} \
--base-address ${BASE_ADDRESS} \
-f ${m2libc}/${ARCH}/ELF-${ARCH}-debug.hex2 \
-f ./M2-1.hex2 \
-o ${out}/bin/M2-Planet

View file

@ -0,0 +1,88 @@
{ lib
, derivationWithMeta
, kaem-unwrapped
, M1
, M2
, blood-elf-0
, hex2
, m2libc
, src
, version
}:
let
ARCH = "x86";
BLOOD_FLAG = " ";
BASE_ADDRESS = "0x8048000";
ENDIAN_FLAG = "--little-endian";
# We need a few tools from mescc-tools-extra to assemble the output folder
buildMesccToolsExtraUtil = name:
derivationWithMeta {
pname = "mescc-tools-extra-${name}";
builder = kaem-unwrapped;
args = [
"--verbose"
"--strict"
"--file"
(builtins.toFile "build-${name}.kaem" ''
''${M2} --architecture ''${ARCH} \
-f ''${m2libc}/sys/types.h \
-f ''${m2libc}/stddef.h \
-f ''${m2libc}/''${ARCH}/linux/fcntl.c \
-f ''${m2libc}/fcntl.c \
-f ''${m2libc}/''${ARCH}/linux/unistd.c \
-f ''${m2libc}/''${ARCH}/linux/sys/stat.c \
-f ''${m2libc}/stdlib.c \
-f ''${m2libc}/stdio.h \
-f ''${m2libc}/stdio.c \
-f ''${m2libc}/string.c \
-f ''${m2libc}/bootstrappable.c \
-f ''${src}/mescc-tools-extra/${name}.c \
--debug \
-o ${name}.M1
''${blood-elf-0} ''${ENDIAN_FLAG} -f ${name}.M1 -o ${name}-footer.M1
''${M1} --architecture ''${ARCH} \
''${ENDIAN_FLAG} \
-f ''${m2libc}/''${ARCH}/''${ARCH}_defs.M1 \
-f ''${m2libc}/''${ARCH}/libc-full.M1 \
-f ${name}.M1 \
-f ${name}-footer.M1 \
-o ${name}.hex2
''${hex2} --architecture ''${ARCH} \
''${ENDIAN_FLAG} \
-f ''${m2libc}/''${ARCH}/ELF-''${ARCH}-debug.hex2 \
-f ${name}.hex2 \
--base-address ''${BASE_ADDRESS} \
-o ''${out}
'')
];
inherit version M1 M2 blood-elf-0 hex2 m2libc src ARCH BLOOD_FLAG BASE_ADDRESS ENDIAN_FLAG;
};
mkdir = buildMesccToolsExtraUtil "mkdir";
cp = buildMesccToolsExtraUtil "cp";
chmod = buildMesccToolsExtraUtil "chmod";
replace = buildMesccToolsExtraUtil "replace";
in
derivationWithMeta {
pname = "mescc-tools";
builder = kaem-unwrapped;
args = [
"--verbose"
"--strict"
"--file"
./build.kaem
];
inherit version M1 M2 blood-elf-0 hex2 mkdir cp chmod replace m2libc src ARCH BLOOD_FLAG BASE_ADDRESS ENDIAN_FLAG;
meta = with lib; {
description = "Collection of tools written for use in bootstrapping";
homepage = "https://github.com/oriansj/mescc-tools";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
}

View file

@ -0,0 +1,345 @@
# This is a translation of stage0-posix/stage0-posix/x86/mescc-tools-mini-kaem.kaem to nix
# https://github.com/oriansj/stage0-posix-x86/blob/56e6b8df3e95f4bc04f8b420a4cd8c82c70b9efa/mescc-tools-mini-kaem.kaem
#
# We have access to mini-kaem at this point but it doesn't support substituting
# environment variables. Without variables there's no way of passing in store inputs,
# or the $out path, other than as command line arguments directly
# Mes --- Maxwell Equations of Software
# Copyright © 2017,2019 Jan Nieuwenhuizen <janneke@gnu.org>
# Copyright © 2017,2019 Jeremiah Orians
#
# This file is part of Mes.
#
# Mes is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# Mes is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mes. If not, see <http://www.gnu.org/licenses/>.
# Warning all binaries prior to the use of blood-elf will not be readable by
# Objdump, you may need to use ndism or gdb to view the assembly in the binary.
{ lib
, derivationWithMeta
, hex0
, m2libc
, src
, version
}:
rec {
out = placeholder "out";
run = pname: builder: args:
derivationWithMeta {
inherit pname version builder args;
meta = with lib; {
description = "Collection of tools written for use in bootstrapping";
homepage = "https://github.com/oriansj/stage0-posix";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
};
################################
# Phase-1 Build hex1 from hex0 #
################################
hex1 = run "hex1" hex0 ["${src}/x86/hex1_x86.hex0" out];
# hex1 adds support for single character labels and is available in various forms
# in mescc-tools/x86_bootstrap to allow you various ways to verify correctness
################################
# Phase-2 Build hex2 from hex1 #
################################
hex2-0 = run "hex2" hex1 ["${src}/x86/hex2_x86.hex1" out];
# hex2 adds support for long labels and absolute addresses thus allowing it
# to function as an effective linker for later stages of the bootstrap
# This is a minimal version which will be used to bootstrap a much more advanced
# version in a later stage.
#################################
# Phase-2b Build catm from hex2 #
#################################
catm = run "catm" hex2-0 ["${src}/x86/catm_x86.hex2" out];
# catm removes the need for cat or shell support for redirection by providing
# equivalent functionality via catm output_file input1 input2 ... inputN
##############################
# Phase-3 Build M0 from hex2 #
##############################
M0_hex2 = run "M0.hex2" catm [out "${src}/x86/ELF-i386.hex2" "${src}/x86/M0_x86.hex2"];
M0 = run "M0" hex2-0 [M0_hex2 out];
# M0 is the architecture specific version of M1 and is by design single
# architecture only and will be replaced by the C code version of M1
################################
# Phase-4 Build cc_x86 from M0 #
################################
cc_x86-0_hex2 = run "cc_x86-0.hex2" M0 ["${src}/x86/cc_x86.M1" out];
cc_x86-1_hex2 = run "cc_x86-1.hex2" catm [out "${src}/x86/ELF-i386.hex2" cc_x86-0_hex2];
cc_x86 = run "cc_x86" hex2-0 [cc_x86-1_hex2 out];
#######################################
# Phase-5 Build M2-Planet from cc_x86 #
#######################################
M2-0_c = run "M2-0.c" catm [
out
"${m2libc}/x86/linux/bootstrap.c"
"${src}/M2-Planet/cc.h"
"${m2libc}/bootstrappable.c"
"${src}/M2-Planet/cc_globals.c"
"${src}/M2-Planet/cc_reader.c"
"${src}/M2-Planet/cc_strings.c"
"${src}/M2-Planet/cc_types.c"
"${src}/M2-Planet/cc_core.c"
"${src}/M2-Planet/cc_macro.c"
"${src}/M2-Planet/cc.c"
];
M2-0_M1 = run "M2-0.M1" cc_x86 [M2-0_c out];
M2-0-0_M1 = run "M2-0-0.M1" catm [out "${src}/x86/x86_defs.M1" "${src}/x86/libc-core.M1" M2-0_M1];
M2-0_hex2 = run "M2-0.hex2" M0 [M2-0-0_M1 out];
M2-0-0_hex2 = run "M2-0-0.hex2" catm [out "${src}/x86/ELF-i386.hex2" M2-0_hex2];
M2 = run "M2" hex2-0 [M2-0-0_hex2 out];
############################################
# Phase-6 Build blood-elf-0 from C sources #
############################################
blood-elf-0_M1 = run "blood-elf-0.M1" M2 [
"--architecture" "x86"
"-f" "${m2libc}/x86/linux/bootstrap.c"
"-f" "${m2libc}/bootstrappable.c"
"-f" "${src}/mescc-tools/stringify.c"
"-f" "${src}/mescc-tools/blood-elf.c"
"--bootstrap-mode"
"-o" out
];
blood-elf-0-0_M1 = run "blood-elf-0-0.M1" catm [out "${m2libc}/x86/x86_defs.M1" "${m2libc}/x86/libc-core.M1" blood-elf-0_M1];
blood-elf-0_hex2 = run "blood-elf-0.hex2" M0 [blood-elf-0-0_M1 out];
blood-elf-0-0_hex2 = run "blood-elf-0-0.hex2" catm [out "${m2libc}/x86/ELF-x86.hex2" blood-elf-0_hex2];
blood-elf-0 = run "blood-elf-0" hex2-0 [blood-elf-0-0_hex2 out];
# This is the last stage where the binaries will not have debug info
# and the last piece built that isn't part of the output binaries
#####################################
# Phase-7 Build M1-0 from C sources #
#####################################
M1-macro-0_M1 = run "M1-macro-0.M1" M2 [
"--architecture" "x86"
"-f" "${m2libc}/x86/linux/bootstrap.c"
"-f" "${m2libc}/bootstrappable.c"
"-f" "${src}/mescc-tools/stringify.c"
"-f" "${src}/mescc-tools/M1-macro.c"
"--bootstrap-mode"
"--debug"
"-o" out
];
M1-macro-0-footer_M1 = run "M1-macro-0-footer.M1" blood-elf-0 ["-f" M1-macro-0_M1 "--little-endian" "-o" out];
M1-macro-0-0_M1 = run "M1-macro-0-0.M1" catm [out "${m2libc}/x86/x86_defs.M1" "${m2libc}/x86/libc-core.M1" M1-macro-0_M1 M1-macro-0-footer_M1];
M1-macro-0_hex2 = run "M1-macro-0.hex2" M0 [M1-macro-0-0_M1 out];
M1-macro-0-0_hex2 = run "M1-macro-0-0.hex2" catm [out "${m2libc}/x86/ELF-x86-debug.hex2" M1-macro-0_hex2];
M1-0 = run "M1-0" hex2-0 [M1-macro-0-0_hex2 out];
# This is the last stage where catm will need to be used and the last stage where
# M0 is used, as we will being using it's much more powerful and cross-platform
# version with a bunch of extra goodies.
#######################################
# Phase-8 Build hex2-1 from C sources #
#######################################
hex2_linker-0_M1 = run "hex2_linker-0.M1" M2 [
"--architecture" "x86"
"-f" "${m2libc}/sys/types.h"
"-f" "${m2libc}/stddef.h"
"-f" "${m2libc}/x86/linux/unistd.c"
"-f" "${m2libc}/x86/linux/fcntl.c"
"-f" "${m2libc}/fcntl.c"
"-f" "${m2libc}/x86/linux/sys/stat.c"
"-f" "${m2libc}/stdlib.c"
"-f" "${m2libc}/stdio.h"
"-f" "${m2libc}/stdio.c"
"-f" "${m2libc}/bootstrappable.c"
"-f" "${src}/mescc-tools/hex2.h"
"-f" "${src}/mescc-tools/hex2_linker.c"
"-f" "${src}/mescc-tools/hex2_word.c"
"-f" "${src}/mescc-tools/hex2.c"
"--debug"
"-o" out
];
hex2_linker-0-footer_M1 = run "hex2_linker-0-footer.M1" blood-elf-0 ["-f" hex2_linker-0_M1 "--little-endian" "-o" out];
hex2_linker-0_hex2 = run "hex2_linker-0.hex2" M1-0 [
"--architecture" "x86"
"--little-endian"
"-f" "${m2libc}/x86/x86_defs.M1"
"-f" "${m2libc}/x86/libc-full.M1"
"-f" hex2_linker-0_M1
"-f" hex2_linker-0-footer_M1
"-o" out
];
hex2_linker-0-0_hex2 = run "hex2_linker-0-0.hex2" catm [out "${m2libc}/x86/ELF-x86-debug.hex2" hex2_linker-0_hex2];
hex2-1 = run "hex2-1" hex2-0 [hex2_linker-0-0_hex2 out];
# This is the last stage where we will be using the handwritten hex2 and instead
# be using the far more powerful, cross-platform version with a bunch more goodies
###################################
# Phase-9 Build M1 from C sources #
###################################
M1-macro-1_M1 = run "M1-macro-1.M1" M2 [
"--architecture" "x86"
"-f" "${m2libc}/sys/types.h"
"-f" "${m2libc}/stddef.h"
"-f" "${m2libc}/x86/linux/fcntl.c"
"-f" "${m2libc}/fcntl.c"
"-f" "${m2libc}/x86/linux/unistd.c"
"-f" "${m2libc}/string.c"
"-f" "${m2libc}/stdlib.c"
"-f" "${m2libc}/stdio.h"
"-f" "${m2libc}/stdio.c"
"-f" "${m2libc}/bootstrappable.c"
"-f" "${src}/mescc-tools/stringify.c"
"-f" "${src}/mescc-tools/M1-macro.c"
"--debug"
"-o" out
];
M1-macro-1-footer_M1 = run "M1-macro-1-footer.M1" blood-elf-0 ["-f" M1-macro-1_M1 "--little-endian" "-o" out];
M1-macro-1_hex2 = run "M1-macro-1.hex2" M1-0 [
"--architecture" "x86"
"--little-endian"
"-f" "${m2libc}/x86/x86_defs.M1"
"-f" "${m2libc}/x86/libc-full.M1"
"-f" M1-macro-1_M1
"-f" M1-macro-1-footer_M1
"-o" out
];
M1 = run "M1" hex2-1 [
"--architecture" "x86"
"--little-endian"
"--base-address" "0x8048000"
"-f" "${m2libc}/x86/ELF-x86-debug.hex2"
"-f" M1-macro-1_hex2
"-o" out
];
######################################
# Phase-10 Build hex2 from C sources #
######################################
hex2_linker-2_M1 = run "hex2_linker-2.M1" M2 [
"--architecture" "x86"
"-f" "${m2libc}/sys/types.h"
"-f" "${m2libc}/stddef.h"
"-f" "${m2libc}/x86/linux/unistd.c"
"-f" "${m2libc}/x86/linux/fcntl.c"
"-f" "${m2libc}/fcntl.c"
"-f" "${m2libc}/x86/linux/sys/stat.c"
"-f" "${m2libc}/stdlib.c"
"-f" "${m2libc}/stdio.h"
"-f" "${m2libc}/stdio.c"
"-f" "${m2libc}/bootstrappable.c"
"-f" "${src}/mescc-tools/hex2.h"
"-f" "${src}/mescc-tools/hex2_linker.c"
"-f" "${src}/mescc-tools/hex2_word.c"
"-f" "${src}/mescc-tools/hex2.c"
"--debug"
"-o" out
];
hex2_linker-2-footer_M1 = run "hex2_linker-2-footer.M1" blood-elf-0 ["-f" hex2_linker-2_M1 "--little-endian" "-o" out];
hex2_linker-2_hex2 = run "hex2_linker-2.hex2" M1 [
"--architecture" "x86"
"--little-endian"
"-f" "${m2libc}/x86/x86_defs.M1"
"-f" "${m2libc}/x86/libc-full.M1"
"-f" hex2_linker-2_M1
"-f" hex2_linker-2-footer_M1
"-o" out
];
hex2 = run "hex2" hex2-1 [
"--architecture" "x86"
"--little-endian"
"--base-address" "0x8048000"
"-f" "${m2libc}/x86/ELF-x86-debug.hex2"
"-f" hex2_linker-2_hex2
"-o" out
];
######################################
# Phase-11 Build kaem from C sources #
######################################
kaem_M1 = run "kaem.M1" M2 [
"--architecture" "x86"
"-f" "${m2libc}/sys/types.h"
"-f" "${m2libc}/stddef.h"
"-f" "${m2libc}/string.c"
"-f" "${m2libc}/x86/linux/unistd.c"
"-f" "${m2libc}/x86/linux/fcntl.c"
"-f" "${m2libc}/fcntl.c"
"-f" "${m2libc}/stdlib.c"
"-f" "${m2libc}/stdio.h"
"-f" "${m2libc}/stdio.c"
"-f" "${m2libc}/bootstrappable.c"
"-f" "${src}/mescc-tools/Kaem/kaem.h"
"-f" "${src}/mescc-tools/Kaem/variable.c"
"-f" "${src}/mescc-tools/Kaem/kaem_globals.c"
"-f" "${src}/mescc-tools/Kaem/kaem.c"
"--debug"
"-o" out
];
kaem-footer_M1 = run "kaem-footer.M1" blood-elf-0 ["-f" kaem_M1 "--little-endian" "-o" out];
kaem_hex2 = run "kaem.hex2" M1 [
"--architecture" "x86"
"--little-endian"
"-f" "${m2libc}/x86/x86_defs.M1"
"-f" "${m2libc}/x86/libc-full.M1"
"-f" kaem_M1
"-f" kaem-footer_M1
"-o" out
];
kaem-unwrapped = run "kaem-unwrapped" hex2 [
"--architecture" "x86"
"--little-endian"
"-f" "${m2libc}/x86/ELF-x86-debug.hex2"
"-f" kaem_hex2
"--base-address" "0x8048000"
"-o" out
];
}

View file

@ -0,0 +1,163 @@
# Bootstrappable TCC is a fork from mainline TCC development
# that can be compiled by MesCC
# Build steps adapted from https://github.com/fosslinux/live-bootstrap/blob/1bc4296091c51f53a5598050c8956d16e945b0f5/sysa/tcc-0.9.26/tcc-0.9.26.kaem
#
# SPDX-FileCopyrightText: 2021-22 fosslinux <fosslinux@aussies.space>
#
# SPDX-License-Identifier: GPL-3.0-or-later
{ lib
, runCommand
, callPackage
, fetchurl
, mes
, mes-libc
}:
let
inherit (callPackage ./common.nix { }) buildTinyccMes;
version = "unstable-2023-04-20";
rev = "80114c4da6b17fbaabb399cc29f427e368309bc8";
tarball = fetchurl {
url = "https://gitlab.com/janneke/tinycc/-/archive/${rev}/tinycc-${rev}.tar.gz";
sha256 = "1a0cw9a62qc76qqn5sjmp3xrbbvsz2dxrw21lrnx9q0s74mwaxbq";
};
src = (runCommand "tinycc-bootstrappable-${version}-source" {} ''
ungz --file ${tarball} --output tinycc.tar
mkdir -p ''${out}
cd ''${out}
untar --file ''${NIX_BUILD_TOP}/tinycc.tar
'') + "/tinycc-${rev}";
meta = with lib; {
description = "Tiny C Compiler's bootstrappable fork";
homepage = "https://gitlab.com/janneke/tinycc";
license = licenses.lgpl21Only;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
tinycc-boot-mes = runCommand "tinycc-boot-mes-${version}" {} ''
catm config.h
${mes}/bin/mes --no-auto-compile -e main ${mes}/bin/mescc.scm -- \
-S \
-o tcc.s \
-I . \
-D BOOTSTRAP=1 \
-I ${src} \
-D TCC_TARGET_I386=1 \
-D inline= \
-D CONFIG_TCCDIR=\"''${out}/lib\" \
-D CONFIG_SYSROOT=\"\" \
-D CONFIG_TCC_CRTPREFIX=\"''${out}/lib\" \
-D CONFIG_TCC_ELFINTERP=\"/mes/loader\" \
-D CONFIG_TCC_SYSINCLUDEPATHS=\"${mes-libc}/include\" \
-D TCC_LIBGCC=\"${mes-libc}/lib/x86-mes/libc.a\" \
-D CONFIG_TCC_LIBTCC1_MES=0 \
-D CONFIG_TCCBOOT=1 \
-D CONFIG_TCC_STATIC=1 \
-D CONFIG_USE_LIBGCC=1 \
-D TCC_MES_LIBC=1 \
-D TCC_VERSION=\"${version}\" \
-D ONE_SOURCE=1 \
${src}/tcc.c
mkdir -p ''${out}/bin
${mes}/bin/mes --no-auto-compile -e main ${mes}/bin/mescc.scm -- \
-l c+tcc \
-o ''${out}/bin/tcc \
tcc.s
''${out}/bin/tcc -version
# Recompile libc: crt{1,n,i}, libtcc.a, libc.a, libgetopt.a
mkdir -p ''${out}/lib
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o ''${out}/lib/crt1.o ${mes-libc}/lib/crt1.c
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o ''${out}/lib/crtn.o ${mes-libc}/lib/crtn.c
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o ''${out}/lib/crti.o ${mes-libc}/lib/crti.c
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o libc.o ${mes-libc}/lib/libc.c
''${out}/bin/tcc -ar cr ''${out}/lib/libc.a libc.o
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o libtcc1.o ${mes-libc}/lib/libtcc1.c
''${out}/bin/tcc -ar cr ''${out}/lib/libtcc1.a libtcc1.o
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o libgetopt.o ${mes-libc}/lib/libgetopt.c
''${out}/bin/tcc -ar cr ''${out}/lib/libgetopt.a libgetopt.o
'';
# Bootstrap stage build flags obtained from
# https://gitlab.com/janneke/tinycc/-/blob/80114c4da6b17fbaabb399cc29f427e368309bc8/boot.sh
tinycc-boot0 = buildTinyccMes {
pname = "tinycc-boot0";
inherit src version meta;
prev = tinycc-boot-mes;
buildOptions = [
"-D HAVE_LONG_LONG_STUB=1"
"-D HAVE_SETJMP=1"
];
libtccBuildOptions = [
"-D HAVE_LONG_LONG_STUB=1"
];
};
tinycc-boot1 = buildTinyccMes {
pname = "tinycc-boot1";
inherit src version meta;
prev = tinycc-boot0;
buildOptions = [
"-D HAVE_BITFIELD=1"
"-D HAVE_LONG_LONG=1"
"-D HAVE_SETJMP=1"
];
libtccBuildOptions = [
"-D HAVE_LONG_LONG=1"
];
};
tinycc-boot2 = buildTinyccMes {
pname = "tinycc-boot2";
inherit src version meta;
prev = tinycc-boot1;
buildOptions = [
"-D HAVE_BITFIELD=1"
"-D HAVE_FLOAT_STUB=1"
"-D HAVE_LONG_LONG=1"
"-D HAVE_SETJMP=1"
];
libtccBuildOptions = [
"-D HAVE_FLOAT_STUB=1"
"-D HAVE_LONG_LONG=1"
];
};
tinycc-boot3 = buildTinyccMes {
pname = "tinycc-boot3";
inherit src version meta;
prev = tinycc-boot2;
buildOptions = [
"-D HAVE_BITFIELD=1"
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
"-D HAVE_SETJMP=1"
];
libtccBuildOptions = [
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
];
};
in
buildTinyccMes {
pname = "tinycc-bootstrappable";
inherit src version meta;
prev = tinycc-boot3;
buildOptions = [
"-D HAVE_BITFIELD=1"
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
"-D HAVE_SETJMP=1"
];
libtccBuildOptions = [
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
];
}

View file

@ -0,0 +1,69 @@
{ lib
, runCommand
, mes-libc
, ln-boot
}:
{
buildTinyccMes = {
pname,
version,
src,
prev,
buildOptions,
libtccBuildOptions,
meta
}:
let
options = lib.strings.concatStringsSep " " buildOptions;
libtccOptions = lib.strings.concatStringsSep " " libtccBuildOptions;
in
runCommand "${pname}-${version}" {
inherit pname version meta;
nativeBuildInputs = [ ln-boot ];
} ''
catm config.h
mkdir -p ''${out}/bin
${prev}/bin/tcc \
-g \
-v \
-static \
-o ''${out}/bin/tcc \
-D BOOTSTRAP=1 \
${options} \
-I . \
-I ${src} \
-D TCC_TARGET_I386=1 \
-D CONFIG_TCCDIR=\"''${out}/lib\" \
-D CONFIG_TCC_CRTPREFIX=\"''${out}/lib\" \
-D CONFIG_TCC_ELFINTERP=\"\" \
-D CONFIG_TCC_LIBPATHS=\"''${out}/lib\" \
-D CONFIG_TCC_SYSINCLUDEPATHS=\"${mes-libc}/include:${src}/include\" \
-D TCC_LIBGCC=\"libc.a\" \
-D TCC_LIBTCC1=\"libtcc1.a\" \
-D CONFIG_TCCBOOT=1 \
-D CONFIG_TCC_STATIC=1 \
-D CONFIG_USE_LIBGCC=1 \
-D TCC_MES_LIBC=1 \
-D TCC_VERSION=\"${version}\" \
-D ONE_SOURCE=1 \
-L ${prev}/lib \
${src}/tcc.c
''${out}/bin/tcc -v
# Recompile libc: crt{1,n,i}, libtcc.a, libc.a, libgetopt.a
mkdir -p ''${out}/lib
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o ''${out}/lib/crt1.o ${mes-libc}/lib/crt1.c
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o ''${out}/lib/crtn.o ${mes-libc}/lib/crtn.c
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o ''${out}/lib/crti.o ${mes-libc}/lib/crti.c
''${out}/bin/tcc -c -D TCC_TARGET_I386=1 ${libtccOptions} -o libtcc1.o ${src}/lib/libtcc1.c
''${out}/bin/tcc -ar cr ''${out}/lib/libtcc1.a libtcc1.o
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o libc.o ${mes-libc}/lib/libc.c
''${out}/bin/tcc -ar cr ''${out}/lib/libc.a libc.o
''${out}/bin/tcc ${mes-libc.CFLAGS} -c -o libgetopt.o ${mes-libc}/lib/libgetopt.c
''${out}/bin/tcc -ar cr ''${out}/lib/libgetopt.a libgetopt.o
# Install headers
ln -s ${mes-libc}/include ''${out}/include
'';
}

View file

@ -0,0 +1,87 @@
# Build steps adapted from https://github.com/fosslinux/live-bootstrap/blob/1bc4296091c51f53a5598050c8956d16e945b0f5/sysa/tcc-0.9.27/tcc-0.9.27.kaem
#
# SPDX-FileCopyrightText: 2021-22 fosslinux <fosslinux@aussies.space>
#
# SPDX-License-Identifier: GPL-3.0-or-later
{ lib
, runCommand
, fetchurl
, callPackage
, tinycc-bootstrappable
}:
let
inherit (callPackage ./common.nix { }) buildTinyccMes;
version = "unstable-2023-04-20";
rev = "86f3d8e33105435946383aee52487b5ddf918140";
tarball = fetchurl {
url = "https://repo.or.cz/tinycc.git/snapshot/${rev}.tar.gz";
sha256 = "11idrvbwfgj1d03crv994mpbbbyg63j1k64lw1gjy7mkiifw2xap";
};
src = (runCommand "tinycc-${version}-source" {} ''
ungz --file ${tarball} --output tinycc.tar
mkdir -p ''${out}
cd ''${out}
untar --file ''${NIX_BUILD_TOP}/tinycc.tar
'') + "/tinycc-${builtins.substring 0 7 rev}";
meta = with lib; {
description = "Small, fast, and embeddable C compiler and interpreter";
homepage = "https://repo.or.cz/w/tinycc.git";
license = licenses.lgpl21Only;
maintainers = with maintainers; [ emilytrau ];
platforms = [ "i686-linux" ];
};
tccdefs = runCommand "tccdefs-${version}" {} ''
mkdir ''${out}
${tinycc-bootstrappable}/bin/tcc -static -DC2STR -o c2str ${src}/conftest.c
./c2str ${src}/include/tccdefs.h ''${out}/tccdefs_.h
'';
tinycc-mes-boot = buildTinyccMes {
pname = "tinycc-mes-boot";
inherit src version meta;
prev = tinycc-bootstrappable;
buildOptions = [
"-D HAVE_BITFIELD=1"
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
"-D HAVE_SETJMP=1"
"-D CONFIG_TCC_PREDEFS=1"
"-I ${tccdefs}"
"-D CONFIG_TCC_SEMLOCK=0"
];
libtccBuildOptions = [
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
"-D CONFIG_TCC_PREDEFS=1"
"-I ${tccdefs}"
"-D CONFIG_TCC_SEMLOCK=0"
];
};
in
buildTinyccMes {
pname = "tinycc-mes";
inherit src version meta;
prev = tinycc-mes-boot;
buildOptions = [
"-std=c99"
"-D HAVE_BITFIELD=1"
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
"-D HAVE_SETJMP=1"
"-D CONFIG_TCC_PREDEFS=1"
"-I ${tccdefs}"
"-D CONFIG_TCC_SEMLOCK=0"
];
libtccBuildOptions = [
"-D HAVE_FLOAT=1"
"-D HAVE_LONG_LONG=1"
"-D CONFIG_TCC_PREDEFS=1"
"-I ${tccdefs}"
"-D CONFIG_TCC_SEMLOCK=0"
];
}

View file

@ -0,0 +1,83 @@
{ lib
, buildPlatform
, callPackage
, kaem
, mescc-tools
, mescc-tools-extra
}:
let
checkMeta = callPackage ../../../stdenv/generic/check-meta.nix { };
in
rec {
fetchurl = import ../../../build-support/fetchurl/boot.nix {
inherit (buildPlatform) system;
};
derivationWithMeta = attrs:
let
passthru = attrs.passthru or {};
validity = checkMeta.assertValidity { inherit meta attrs; };
meta = checkMeta.commonMeta { inherit validity attrs; };
in
lib.extendDerivation
validity.handled
({ inherit meta passthru; } // passthru)
(derivation ({
inherit (buildPlatform) system;
inherit (meta) name;
} // (builtins.removeAttrs attrs [ "meta" "passthru" ])));
writeTextFile =
{ name # the name of the derivation
, text
, executable ? false # run chmod +x ?
, destination ? "" # relative path appended to $out eg "/bin/foo"
, allowSubstitutes ? false
, preferLocalBuild ? true
}:
derivationWithMeta {
inherit name text executable allowSubstitutes preferLocalBuild;
passAsFile = [ "text" ];
builder = "${kaem}/bin/kaem";
args = [
"--verbose"
"--strict"
"--file"
(builtins.toFile "write-text-file.kaem" ''
target=''${out}''${destination}
if match x''${mkdirDestination} x1; then
mkdir -p ''${out}''${destinationDir}
fi
cp ''${textPath} ''${target}
if match x''${executable} x1; then
chmod 555 ''${target}
fi
'')
];
PATH = lib.makeBinPath [ mescc-tools-extra ];
mkdirDestination = if builtins.dirOf destination == "." then "0" else "1";
destinationDir = builtins.dirOf destination;
inherit destination;
};
writeText = name: text: writeTextFile {inherit name text;};
runCommand = name: env: buildCommand:
derivationWithMeta ({
inherit name;
builder = "${kaem}/bin/kaem";
args = [
"--verbose"
"--strict"
"--file"
(writeText "${name}-builder" buildCommand)
];
PATH = lib.makeBinPath ((env.nativeBuildInputs or []) ++ [ kaem mescc-tools mescc-tools-extra ]);
} // (builtins.removeAttrs env [ "nativeBuildInputs" ]));
}

View file

@ -26994,6 +26994,11 @@ with pkgs;
metastore = callPackage ../os-specific/linux/metastore { };
minimal-bootstrap = recurseIntoAttrs (import ../os-specific/linux/minimal-bootstrap {
inherit (stdenv) buildPlatform hostPlatform;
inherit lib config;
});
mingetty = callPackage ../os-specific/linux/mingetty { };
miraclecast = callPackage ../os-specific/linux/miraclecast { };