Skip to content

Commit 99c4498

Browse files
committed
Merge remote-tracking branch 'remotes/bsdimp/tags/pull-bsd-user-20210910' into staging
This series of patches gets me to the point that I can run "Hello World" on i386 and x86_64. This is for static binaries only, that are relatively small, but it's better than the 100% instant mmap failre that is the current state of all things bsd-user in upstream qemu. Future patch sets will refine this, add the missing system calls, fix bugs preventing more sophisticated programms from running and add a bunch of new architecture support. There's three large themes in these patches, though the changes that represent them are interrelated making it hard to separate out further. 1. Reorganization to support multiple OS and architectures (though I've only tested FreeBSD, other BSDs might not even compile yet). 2. Diff reduction with the bsd-user fork for several files. These diffs include changes that borrowed from linux-user as well as changes to make things work on FreeBSD. The records keeping when this was done, however, was poor at best, so many of the specific borrowings are going unacknowledged here, apart from this general ack. These diffs also include some minor code shuffling. Some of the changes are done specifically to make it easier to rebase the bsd-user fork's changes when these land in the tree (a number of changes have been pushed there to make this more possible). 3. Filling in the missing pieces to make things work. There's many changes to elfload to make it load things in the right places, to find the interpreter better, etc. There's changes to mmap.c to make the mappings work better and there's changes to main.c that were inspired, at least, by now-ancient changes to linux-user's main.c. I ran checkpatch.pl on this, and there's 350-odd errors it identifies (the vast majoirty come from BSD's fetish for tabs), so there will need to be a V2 to fix this at the very least. In addition, the change set is big (about +~4.5k/-~2.5k lines), so I anticipate some iteration as well just based on its sheer size. I've tried to keep each set small to make it easy to review in isolation, but I've also allowed some interrelated ones to get a little bigger than I'd normally like. I've not done the customary documentation of the expected checkpatch.pl output because it is large, and because I wanted to get review of the other parts rolling to get this project unstuck. Future versions of the patch will document the expected output. In addition, I noticed a number of places where I could modernize to make the code match things like linux-user better. I've resisted the urge to do these at this time, since it would complicate merging the other ~30k lines of diff that remains after this batch. Future batches should generally be smaller once this one has landed since they are, by and large, either a bunch of new files to support armv7, aarch64, riscv64, mips, mipsel, mips64, ppc, ppc64 and ppc64le, or are adding system calls, which can be done individually or small groups. I've removed sparc and sparc64 support as they've been removed from FreeBSD and have been near totally busted for years. Stacey Son did the bulk of this work originally, but since I had to move things around so much and/or retool that work in non-trivial ways, I've kept myself as author, and added his signed-off-by line. I'm unsure of the qemu standard practice for this, but am happy to learn if this is too far outside its current mainstream. For a while Sean Bruno did the merges from upstream, and he's credited using his signed-off-by in appropriate places, though for this patch set there's only a few. I've tried to ensure that others who have work in individual patches that I've aggregated together also are reflected in their signed-off-by. Given the chaotic stat of the upstream repo for its early history, this may be the best that can be reconstructed at this late date. Most of these files are 'foundational' so have existed from the earliest days when record keeping wasn't quite what I'd wish for in hindsight. There was only really one change that I could easily cherry-pick (Colin's), so I did that. # gpg: Signature made Fri 10 Sep 2021 21:24:08 BST # gpg: using RSA key 2035F894B00AA3CF7CCDE1B76C1CD1287DB01100 # gpg: Good signature from "Warner Losh <[email protected]>" [unknown] # gpg: aka "Warner Losh <[email protected]>" [unknown] # gpg: aka "Warner Losh <[email protected]>" [unknown] # gpg: aka "Warner Losh <[email protected]>" [unknown] # gpg: aka "Warner Losh <[email protected]>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 2035 F894 B00A A3CF 7CCD E1B7 6C1C D128 7DB0 1100 * remotes/bsdimp/tags/pull-bsd-user-20210910: (42 commits) bsd-user: Update mapping to handle reserved and starting conditions bsd-user: Add '-0 argv0' option to bsd-user/main.c bsd-user: Implement interlock for atomic operations bsd-user: move gemu_log to later in the file bsd-user: Refactor load_elf_sections and is_target_elf_binary bsd-user: elfload.c style catch up patch bsd-user: add stubbed out core dump support bsd-user: Add target_os_user.h to capture the user/kernel structures bsd-user: Add target_arch_reg to describe a target's register set bsd-user: update debugging in mmap.c bsd-user: Rewrite target system call definintion glue bsd-user: Remove dead #ifdefs from elfload.c bsd-user: elf cleanup bsd-user: Add architecture specific signal tramp code bsd-user: Move stack initializtion into a per-os file. bsd-user: Implement --seed and initialize random state bsd-user: *BSD specific siginfo defintions bsd-user: Add system independent stack, data and text limiting bsd-user: Create target specific vmparam.h bsd-user: define max args in terms of pages ... Signed-off-by: Peter Maydell <[email protected]>
2 parents 3bb6040 + be04f21 commit 99c4498

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+4386
-2263
lines changed

bsd-user/bsd-mman.h

Lines changed: 0 additions & 121 deletions
This file was deleted.

bsd-user/bsdload.c

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
/* Code for loading BSD executables. Mostly linux kernel code. */
1+
/*
2+
* Load BSD executables.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, see <http://www.gnu.org/licenses/>.
16+
*/
217

318
#include "qemu/osdep.h"
419

520
#include "qemu.h"
621

7-
#define TARGET_NGROUPS 32
8-
922
/* ??? This should really be somewhere else. */
1023
abi_long memcpy_to_target(abi_ulong dest, const void *src,
1124
unsigned long len)
@@ -83,7 +96,7 @@ static int prepare_binprm(struct bsd_binprm *bprm)
8396

8497
/* Construct the envp and argv tables on the target stack. */
8598
abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
86-
abi_ulong stringp, int push_ptr)
99+
abi_ulong stringp)
87100
{
88101
int n = sizeof(abi_ulong);
89102
abi_ulong envp;
@@ -93,13 +106,6 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
93106
envp = sp;
94107
sp -= (argc + 1) * n;
95108
argv = sp;
96-
if (push_ptr) {
97-
/* FIXME - handle put_user() failures */
98-
sp -= n;
99-
put_user_ual(envp, sp);
100-
sp -= n;
101-
put_user_ual(argv, sp);
102-
}
103109
sp -= n;
104110
/* FIXME - handle put_user() failures */
105111
put_user_ual(argc, sp);
@@ -124,36 +130,70 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
124130
return sp;
125131
}
126132

133+
static bool is_there(const char *candidate)
134+
{
135+
struct stat fin;
136+
137+
/* XXX work around access(2) false positives for superuser */
138+
if (access(candidate, X_OK) == 0 && stat(candidate, &fin) == 0 &&
139+
S_ISREG(fin.st_mode) && (getuid() != 0 ||
140+
(fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) {
141+
return true;
142+
}
143+
144+
return false;
145+
}
146+
127147
int loader_exec(const char *filename, char **argv, char **envp,
128-
struct target_pt_regs *regs, struct image_info *infop)
148+
struct target_pt_regs *regs, struct image_info *infop,
149+
struct bsd_binprm *bprm)
129150
{
130-
struct bsd_binprm bprm;
131-
int retval;
132-
int i;
151+
char *path, fullpath[PATH_MAX];
152+
int retval, i;
133153

134-
bprm.p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
135-
for (i = 0 ; i < MAX_ARG_PAGES ; i++) { /* clear page-table */
136-
bprm.page[i] = NULL;
154+
bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES;
155+
for (i = 0; i < MAX_ARG_PAGES; i++) { /* clear page-table */
156+
bprm->page[i] = NULL;
137157
}
138-
retval = open(filename, O_RDONLY);
158+
159+
if (strchr(filename, '/') != NULL) {
160+
path = realpath(filename, fullpath);
161+
if (path == NULL) {
162+
/* Failed to resolve. */
163+
return -1;
164+
}
165+
if (!is_there(path)) {
166+
return -1;
167+
}
168+
} else {
169+
path = g_find_program_in_path(filename);
170+
if (path == NULL) {
171+
return -1;
172+
}
173+
}
174+
175+
retval = open(path, O_RDONLY);
139176
if (retval < 0) {
177+
g_free(path);
140178
return retval;
141179
}
142-
bprm.fd = retval;
143-
bprm.filename = (char *)filename;
144-
bprm.argc = count(argv);
145-
bprm.argv = argv;
146-
bprm.envc = count(envp);
147-
bprm.envp = envp;
148180

149-
retval = prepare_binprm(&bprm);
181+
bprm->fullpath = path;
182+
bprm->fd = retval;
183+
bprm->filename = (char *)filename;
184+
bprm->argc = count(argv);
185+
bprm->argv = argv;
186+
bprm->envc = count(envp);
187+
bprm->envp = envp;
188+
189+
retval = prepare_binprm(bprm);
150190

151191
if (retval >= 0) {
152-
if (bprm.buf[0] == 0x7f
153-
&& bprm.buf[1] == 'E'
154-
&& bprm.buf[2] == 'L'
155-
&& bprm.buf[3] == 'F') {
156-
retval = load_elf_binary(&bprm, regs, infop);
192+
if (bprm->buf[0] == 0x7f
193+
&& bprm->buf[1] == 'E'
194+
&& bprm->buf[2] == 'L'
195+
&& bprm->buf[3] == 'F') {
196+
retval = load_elf_binary(bprm, regs, infop);
157197
} else {
158198
fprintf(stderr, "Unknown binary format\n");
159199
return -1;
@@ -168,7 +208,7 @@ int loader_exec(const char *filename, char **argv, char **envp,
168208

169209
/* Something went wrong, return the inode and free the argument pages*/
170210
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
171-
g_free(bprm.page[i]);
211+
g_free(bprm->page[i]);
172212
}
173213
return retval;
174214
}

bsd-user/elfcore.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* Stubbed out version of core dump support, explicitly in public domain */
2+
3+
static int elf_core_dump(int signr, CPUArchState *env)
4+
{
5+
struct elf_note en = { 0 };
6+
7+
bswap_note(&en);
8+
9+
return 0;
10+
}

0 commit comments

Comments
 (0)