Skip to content

Commit baefaa2

Browse files
authored
Merge pull request #33 from Mic92/ci
nix-ld: improve failure message
2 parents a6fd41e + 0a0e050 commit baefaa2

33 files changed

+4080
-20571
lines changed

meson.build

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ configure_file(input : 'config.h.in',
4242

4343
ptr_size = cc.sizeof('void *')
4444

45-
vendor_inc = include_directories('vendor/nolibc', 'src/stdint', 'vendor/printf')
45+
vendor_inc = include_directories('vendor/nolibc')
4646

4747
nix_ld = executable('nix-ld',
4848
['src/nix-ld.c'],

modules/nix-ld.nix

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ in
4242
default = baseLibraries;
4343
};
4444
};
45-
config = lib.mkIf cfg.enable {
45+
config = {
46+
programs.nix-ld.enable = true;
47+
4648
systemd.tmpfiles.packages = [
4749
(pkgs.callPackage ../nix-ld.nix {})
4850
];

src/nix-ld.c

+6-10
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
#include <nolibc.h>
66

77
#include "strerror.h"
8-
#include "mmap.h"
9-
#include <printf.c>
8+
#include <stdio.h>
109
#include <config.h>
1110

1211
#define alloca __builtin_alloca
@@ -55,17 +54,12 @@ static inline void munmapp(mmap_t *m) {
5554
}
5655
}
5756

58-
void _putchar(char c) {
59-
// super slow but we only use print stuff in the error case, so it does not matter.
60-
write(1, &c, 1);
61-
}
62-
6357
static void log_error(struct ld_ctx *ctx, const char *format, ...) {
6458
va_list args;
6559
printf("cannot execute %s: ", ctx->prog_name);
6660

6761
va_start(args, format);
68-
vprintf(format, args);
62+
vfprintf(stdout, format, args);
6963
va_end(args);
7064

7165
// cannot overflow because vsnprintf leaves space for the null byte
@@ -368,7 +362,9 @@ static int update_ld_library_path(struct ld_ctx *ctx) {
368362
}
369363

370364
// same as LD_LIBRARY_PATH=oldvalue:$NIX_LD_LIBRARY_PATH
371-
snprintf(new_str, new_size, "%s%s%s", env, sep, ctx->nix_ld_lib_path);
365+
strlcpy(new_str, env, new_size);
366+
strlcat(new_str, sep, new_size);
367+
strlcat(new_str, ctx->nix_ld_lib_path, new_size);
372368

373369
*ctx->ld_lib_path_envp = new_str;
374370
return 0;
@@ -395,7 +391,7 @@ int main(int argc, char** argv, char** envp) {
395391
struct ld_ctx ctx = init_ld_ctx(argc, argv, envp, auxv);
396392

397393
if (!ctx.nix_ld) {
398-
log_error(&ctx, "NIX_LD or NIX_LD_" NIX_SYSTEM " is not set");
394+
log_error(&ctx, "You are trying to run an unpatched binary on nixos, but you have not configured NIX_LD or NIX_LD_" NIX_SYSTEM ". See https://github.com/Mic92/nix-ld for more details");
399395
return 1;
400396
}
401397

src/stdint/stdint.h

-4
This file was deleted.

vendor/nolibc/arch-aarch64.h

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2+
/*
3+
* AARCH64 specific definitions for NOLIBC
4+
* Copyright (C) 2017-2022 Willy Tarreau <[email protected]>
5+
*/
6+
7+
#ifndef _NOLIBC_ARCH_AARCH64_H
8+
#define _NOLIBC_ARCH_AARCH64_H
9+
10+
/* O_* macros for fcntl/open are architecture-specific */
11+
#define O_RDONLY 0
12+
#define O_WRONLY 1
13+
#define O_RDWR 2
14+
#define O_CREAT 0x40
15+
#define O_EXCL 0x80
16+
#define O_NOCTTY 0x100
17+
#define O_TRUNC 0x200
18+
#define O_APPEND 0x400
19+
#define O_NONBLOCK 0x800
20+
#define O_DIRECTORY 0x4000
21+
22+
/* The struct returned by the newfstatat() syscall. Differs slightly from the
23+
* x86_64's stat one by field ordering, so be careful.
24+
*/
25+
struct sys_stat_struct {
26+
unsigned long st_dev;
27+
unsigned long st_ino;
28+
unsigned int st_mode;
29+
unsigned int st_nlink;
30+
unsigned int st_uid;
31+
unsigned int st_gid;
32+
33+
unsigned long st_rdev;
34+
unsigned long __pad1;
35+
long st_size;
36+
int st_blksize;
37+
int __pad2;
38+
39+
long st_blocks;
40+
long st_atime;
41+
unsigned long st_atime_nsec;
42+
long st_mtime;
43+
44+
unsigned long st_mtime_nsec;
45+
long st_ctime;
46+
unsigned long st_ctime_nsec;
47+
unsigned int __unused[2];
48+
};
49+
50+
/* Syscalls for AARCH64 :
51+
* - registers are 64-bit
52+
* - stack is 16-byte aligned
53+
* - syscall number is passed in x8
54+
* - arguments are in x0, x1, x2, x3, x4, x5
55+
* - the system call is performed by calling svc 0
56+
* - syscall return comes in x0.
57+
* - the arguments are cast to long and assigned into the target registers
58+
* which are then simply passed as registers to the asm code, so that we
59+
* don't have to experience issues with register constraints.
60+
*
61+
* On aarch64, select() is not implemented so we have to use pselect6().
62+
*/
63+
#define __ARCH_WANT_SYS_PSELECT6
64+
65+
#define my_syscall0(num) \
66+
({ \
67+
register long _num __asm__ ("x8") = (num); \
68+
register long _arg1 __asm__ ("x0"); \
69+
\
70+
__asm__ volatile ( \
71+
"svc #0\n" \
72+
: "=r"(_arg1) \
73+
: "r"(_num) \
74+
: "memory", "cc" \
75+
); \
76+
_arg1; \
77+
})
78+
79+
#define my_syscall1(num, arg1) \
80+
({ \
81+
register long _num __asm__ ("x8") = (num); \
82+
register long _arg1 __asm__ ("x0") = (long)(arg1); \
83+
\
84+
__asm__ volatile ( \
85+
"svc #0\n" \
86+
: "=r"(_arg1) \
87+
: "r"(_arg1), \
88+
"r"(_num) \
89+
: "memory", "cc" \
90+
); \
91+
_arg1; \
92+
})
93+
94+
#define my_syscall2(num, arg1, arg2) \
95+
({ \
96+
register long _num __asm__ ("x8") = (num); \
97+
register long _arg1 __asm__ ("x0") = (long)(arg1); \
98+
register long _arg2 __asm__ ("x1") = (long)(arg2); \
99+
\
100+
__asm__ volatile ( \
101+
"svc #0\n" \
102+
: "=r"(_arg1) \
103+
: "r"(_arg1), "r"(_arg2), \
104+
"r"(_num) \
105+
: "memory", "cc" \
106+
); \
107+
_arg1; \
108+
})
109+
110+
#define my_syscall3(num, arg1, arg2, arg3) \
111+
({ \
112+
register long _num __asm__ ("x8") = (num); \
113+
register long _arg1 __asm__ ("x0") = (long)(arg1); \
114+
register long _arg2 __asm__ ("x1") = (long)(arg2); \
115+
register long _arg3 __asm__ ("x2") = (long)(arg3); \
116+
\
117+
__asm__ volatile ( \
118+
"svc #0\n" \
119+
: "=r"(_arg1) \
120+
: "r"(_arg1), "r"(_arg2), "r"(_arg3), \
121+
"r"(_num) \
122+
: "memory", "cc" \
123+
); \
124+
_arg1; \
125+
})
126+
127+
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
128+
({ \
129+
register long _num __asm__ ("x8") = (num); \
130+
register long _arg1 __asm__ ("x0") = (long)(arg1); \
131+
register long _arg2 __asm__ ("x1") = (long)(arg2); \
132+
register long _arg3 __asm__ ("x2") = (long)(arg3); \
133+
register long _arg4 __asm__ ("x3") = (long)(arg4); \
134+
\
135+
__asm__ volatile ( \
136+
"svc #0\n" \
137+
: "=r"(_arg1) \
138+
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
139+
"r"(_num) \
140+
: "memory", "cc" \
141+
); \
142+
_arg1; \
143+
})
144+
145+
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
146+
({ \
147+
register long _num __asm__ ("x8") = (num); \
148+
register long _arg1 __asm__ ("x0") = (long)(arg1); \
149+
register long _arg2 __asm__ ("x1") = (long)(arg2); \
150+
register long _arg3 __asm__ ("x2") = (long)(arg3); \
151+
register long _arg4 __asm__ ("x3") = (long)(arg4); \
152+
register long _arg5 __asm__ ("x4") = (long)(arg5); \
153+
\
154+
__asm__ volatile ( \
155+
"svc #0\n" \
156+
: "=r" (_arg1) \
157+
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
158+
"r"(_num) \
159+
: "memory", "cc" \
160+
); \
161+
_arg1; \
162+
})
163+
164+
#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
165+
({ \
166+
register long _num __asm__ ("x8") = (num); \
167+
register long _arg1 __asm__ ("x0") = (long)(arg1); \
168+
register long _arg2 __asm__ ("x1") = (long)(arg2); \
169+
register long _arg3 __asm__ ("x2") = (long)(arg3); \
170+
register long _arg4 __asm__ ("x3") = (long)(arg4); \
171+
register long _arg5 __asm__ ("x4") = (long)(arg5); \
172+
register long _arg6 __asm__ ("x5") = (long)(arg6); \
173+
\
174+
__asm__ volatile ( \
175+
"svc #0\n" \
176+
: "=r" (_arg1) \
177+
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
178+
"r"(_arg6), "r"(_num) \
179+
: "memory", "cc" \
180+
); \
181+
_arg1; \
182+
})
183+
184+
/* startup code */
185+
__asm__ (".section .text\n"
186+
".weak _start\n"
187+
"_start:\n"
188+
"ldr x0, [sp]\n" // argc (x0) was in the stack
189+
"add x1, sp, 8\n" // argv (x1) = sp
190+
"lsl x2, x0, 3\n" // envp (x2) = 8*argc ...
191+
"add x2, x2, 8\n" // + 8 (skip null)
192+
"add x2, x2, x1\n" // + argv
193+
"and sp, x1, -16\n" // sp must be 16-byte aligned in the callee
194+
"bl main\n" // main() returns the status code, we'll exit with it.
195+
"mov x8, 93\n" // NR_exit == 93
196+
"svc #0\n"
197+
"");
198+
199+
#endif // _NOLIBC_ARCH_AARCH64_H

0 commit comments

Comments
 (0)