1
Fork 0

it compiles at least

This commit is contained in:
Jan-Erik Rediger 2024-05-14 21:06:04 +02:00
parent 4e22a48854
commit 4eaf069485
8 changed files with 206 additions and 16 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
hello*

25
flake.lock Normal file
View file

@ -0,0 +1,25 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1715653339,
"narHash": "sha256-7lR9tpVXviSccl07GXI0+ve/natd24HAkuy1sQp0OlI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "abd6d48f8c77bea7dc51beb2adfa6ed3950d2585",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View file

@ -11,12 +11,14 @@
let
pkgs = nixpkgs.legacyPackages.${system};
harec = pkgs.callPackage ./pkgs/harec.nix { };
#hare = pkgs.callPackage ./pkgs/hare.nix { inherit harec; };
hare = pkgs.callPackage ./pkgs/hare.nix { inherit harec; };
in
{
default = pkgs.mkShell {
buildInputs = [
pkgs.qbe
harec
hare
];
};
});

37
pkgs/hare-as Executable file
View file

@ -0,0 +1,37 @@
set -o pipefail
function header() {
echo
echo
echo "# ----------------------------------------------------------------"
echo ".file \"$1\""
echo "# ----------------------------------------------------------------"
echo
}
args=
code=
until [ $# -eq 0 ]; do
case $1 in
--)
;;
-o|-I|-arch)
args="$args $1 $2"
shift
;;
-*)
args="$args $1"
;;
*)
# file="$(fix_asm $1)"
# # IFS=$'\n'
file=$(cat "$1")
code="$code$(header $1)"$'\n'"$file"
;;
esac
shift
done
echo "jer"
echo "$code" | fix_asm | as $args -

67
pkgs/hare-as.py Executable file
View file

@ -0,0 +1,67 @@
#!/usr/bin/env python3
import re
import sys
from subprocess import Popen, PIPE, STDOUT
def header(filename):
return f"""
# ------------------
.file "{filename}"
# ------------------
"""
REPLACEMENTS = [
(r'^\.section "\.text([^"]*)"(,"([^"]*))?"$', r'.text ; \1, \3'),
(r'^\.section "\.data([^"]*)"$', r'.data ; \1'),
(r'^\.section "\.bss([^"]*)"$', r'.bss ; \1'),
(r'^\.section "\.init_array"(,"([^"]*)")?', r'.section __DATA, .init_array ; \2'),
(r'^\.section "\.fini_array"(,"([^"]*)")?', r'.section __DATA, .fini_array ; \2'),
(r'^\.section "\.test_array"(,"([^"]*)")?', r'.section __DATA, .test_array ; \2'),
(r'^\.section \.abort "([^"]+)"', r'.section __DATA, .abort $COMMENT \1'),
(r'^(\.type .+)', '; \1'),
(r'^(\.global) (rt\..+)', r'\1 _\2'),
(r'^(rt\..+:)', r'_\1'),
(r'^(crypto\.aes\.x86ni_.+:)', r'_\1'),
(r'^(debug\.getfp:)', r'_\1'),
(r'adrp x0, _environ@page', r'adrp x0, _environ@GOTPAGE'),
(r'add x0, x0, _environ@pageoff', r'ldr x0, [x0, _environ@GOTPAGEOFF]'),
]
def fix_asm(code):
for (pattern, repl) in REPLACEMENTS:
code = re.sub(pattern, repl, code, flags=re.MULTILINE)
return code
args = ['as']
files = []
argv = sys.argv[1:]
while len(argv):
if argv[0] == "--":
args.append("--")
elif argv[0] in ["-o", "-I", "-arch"]:
args.append(argv[0])
args.append(argv[1])
argv.pop(0)
elif argv[0][0] == "-":
argv.append(argv[0])
else:
files.append(argv[0])
argv.pop(0)
args.append("-")
code = ""
for file in files:
with open(file) as fp:
content = fp.read()
code += header(file)
code += "\n"
code += fix_asm(content)
code += "\n"
p = Popen(args, stdout=PIPE, stdin=PIPE, stderr=PIPE, text=True)
data = p.communicate(input=code)
print(data[1], end='', file=sys.stderr)
print(data[0], end='')

View file

@ -7,24 +7,45 @@
qbe,
harec,
binutils-unwrapped,
tzdata
tzdata,
python3,
writeScript,
rustc,
}:
let
platform = lib.toLower stdenv.hostPlatform.uname.system;
arch = stdenv.hostPlatform.uname.processor;
qbePlatform = {
x86_64 = "amd64_sysv";
aarch64 = "arm64";
riscv64 = "rv64";
x86_64 = "amd64_apple";
aarch64 = "arm64_apple";
}.${arch};
hareAs = ./hare-as.py;
hareLd = stdenv.mkDerivation (finalAttrs: {
pname = "rust-ld";
version = "1.0";
src = [ ./ld.rs ];
buildInputs = [ rustc ];
unpackPhase = ''
for srcFile in $src; do
cp $srcFile $(stripHash $srcFile)
done
'';
buildPhase = ''
rustc -o rust-ld.bin $src
'';
installPhase = ''
mkdir -p $out/bin
cp rust-ld.bin $out/bin/rust-ld
'';
});
in
stdenv.mkDerivation (finalAttrs: {
pname = "hare";
version = "0.24";
src = builtins.fetchGit {
url = "https://git.sr.ht/~sircmpwn/hare";
url = "https://github.com/hshq/harelang";
ref = "master";
rev = "0cd51184a7acdfd4ef20195d1648622b04477293";
rev = "30d097a7c7f3ccf9e4fc783d1cdae1fd506673c7";
};
patches = [
@ -35,6 +56,7 @@ stdenv.mkDerivation (finalAttrs: {
makeWrapper
qbe
scdoc
python3
];
buildInputs = [
@ -51,20 +73,25 @@ stdenv.mkDerivation (finalAttrs: {
"VERSION=${finalAttrs.version}-nixpkgs"
"QBEFLAGS=-t${qbePlatform}"
"CC=${stdenv.cc.targetPrefix}cc"
"AS=${stdenv.cc.targetPrefix}as"
"LD=${stdenv.cc.targetPrefix}ld"
"AS=${hareAs}"
"LD=${hareLd}/bin/rust-ld"
# Strip the variable of an empty $(SRCDIR)/hare/third-party, since nix does
# not follow the FHS.
"HAREPATH=$(SRCDIR)/hare/stdlib"
];
postConfigure = ''
ln -s configs/linux.mk config.mk
ln -s configs/darwin.mk config.mk
sed -i 's/ @#/ /' Makefile
sed -i 's/ @/ /' Makefile
sed -i 's/ @/ /' makefiles/darwin.aarch64.mk
'';
postFixup = ''
wrapProgram $out/bin/hare \
--prefix PATH : ${lib.makeBinPath [binutils-unwrapped harec qbe]}
--prefix PATH : ${lib.makeBinPath [harec qbe]} \
--set LD ${hareLd}/bin/rust-ld \
--set AS ${hareAs}
'';
setupHook = ./setup-hook.sh;

View file

@ -3,16 +3,15 @@ let
platform = lib.toLower stdenv.hostPlatform.uname.system;
arch = stdenv.hostPlatform.uname.processor;
qbePlatform = {
x86_64 = "amd64_sysv";
aarch64 = "arm64";
riscv64 = "rv64";
x86_64 = "amd64_apple";
aarch64 = "arm64_apple";
}.${arch};
in
stdenv.mkDerivation (finalAttrs: {
pname = "harec";
version = "0.24";
src = builtins.fetchGit {
url = "github.com/hshq/harelang-harec";
url = "https://github.com/hshq/harelang-harec";
ref = "master";
rev = "51446fdef8b39df1fbf4fa2644d3f51f020f974a";
};

32
pkgs/ld.rs Executable file
View file

@ -0,0 +1,32 @@
#!/usr/bin/env -S cargo +nightly -q -Zscript
use std::env;
use std::process::Command;
fn main() {
let mut args = vec![
"-e".to_string(), "_start".to_string(),
"-lSystem".to_string(),
"-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk".to_string()
];
let mut argv: Vec<_> = env::args().skip(1).collect();
while argv.len() > 0 {
let arg = argv.remove(0);
match &*arg {
"-T" | "-z" => {
// Skip next one too
_ = argv.remove(0);
}
"--gc-sections" => { }
_ if arg.starts_with("-T") => { }
_ if arg.starts_with("-z") => { }
_ if arg.starts_with("--script=") => { }
_ => {
args.push(arg);
}
}
}
Command::new("ld").args(&args).status().unwrap();
}