linux-user/flatload.c: Remove unused bFLT shared-library and ZFLAT code
Ever since the bFLT format support was added in 2006, there has been a chunk of code in the file guarded by CONFIG_BINFMT_SHARED_FLAT which is supposedly for shared library support. This is not enabled and it's not possible to enable it, because if you do you'll run into the "#error needs checking" in the calc_reloc() function. Similarly, CONFIG_BINFMT_ZFLAT exists but can't be enabled because of an "#error code needs checking" in load_flat_file(). This code is obviously unfinished and has never been used; nobody in the intervening 18 years has complained about this or fixed it, so just delete the dead code. If anybody ever wants the feature they can always pull it out of git, or (perhaps better) write it from scratch based on the current Linux bFLT loader rather than the one of 18 years ago. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20240411115313.680433-1-peter.maydell@linaro.org
This commit is contained in:
parent
c3a68dfd19
commit
a6819c1bd0
@ -12,11 +12,8 @@
|
|||||||
|
|
||||||
#define FLAT_VERSION 0x00000004L
|
#define FLAT_VERSION 0x00000004L
|
||||||
|
|
||||||
#ifdef CONFIG_BINFMT_SHARED_FLAT
|
/* QEMU doesn't support bflt shared libraries */
|
||||||
#define MAX_SHARED_LIBS (4)
|
|
||||||
#else
|
|
||||||
#define MAX_SHARED_LIBS (1)
|
#define MAX_SHARED_LIBS (1)
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To make everything easier to port and manage cross platform
|
* To make everything easier to port and manage cross platform
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
* JAN/99 -- coded full program relocation (gerg@snapgear.com)
|
* JAN/99 -- coded full program relocation (gerg@snapgear.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ??? ZFLAT and shared library support is currently disabled. */
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
@ -64,10 +62,6 @@ struct lib_info {
|
|||||||
short loaded; /* Has this library been loaded? */
|
short loaded; /* Has this library been loaded? */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_BINFMT_SHARED_FLAT
|
|
||||||
static int load_flat_shared_library(int id, struct lib_info *p);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct linux_binprm;
|
struct linux_binprm;
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -108,153 +102,6 @@ static int target_pread(int fd, abi_ulong ptr, abi_ulong len,
|
|||||||
unlock_user(buf, ptr, len);
|
unlock_user(buf, ptr, len);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_BINFMT_ZFLAT
|
|
||||||
|
|
||||||
#include <linux/zlib.h>
|
|
||||||
|
|
||||||
#define LBUFSIZE 4000
|
|
||||||
|
|
||||||
/* gzip flag byte */
|
|
||||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
|
|
||||||
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
|
|
||||||
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
|
||||||
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
|
|
||||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
|
||||||
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
|
||||||
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
|
||||||
|
|
||||||
static int decompress_exec(
|
|
||||||
struct linux_binprm *bprm,
|
|
||||||
unsigned long offset,
|
|
||||||
char *dst,
|
|
||||||
long len,
|
|
||||||
int fd)
|
|
||||||
{
|
|
||||||
unsigned char *buf;
|
|
||||||
z_stream strm;
|
|
||||||
loff_t fpos;
|
|
||||||
int ret, retval;
|
|
||||||
|
|
||||||
DBG_FLT("decompress_exec(offset=%x,buf=%x,len=%x)\n",(int)offset, (int)dst, (int)len);
|
|
||||||
|
|
||||||
memset(&strm, 0, sizeof(strm));
|
|
||||||
strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
|
|
||||||
if (strm.workspace == NULL) {
|
|
||||||
DBG_FLT("binfmt_flat: no memory for decompress workspace\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
buf = kmalloc(LBUFSIZE, GFP_KERNEL);
|
|
||||||
if (buf == NULL) {
|
|
||||||
DBG_FLT("binfmt_flat: no memory for read buffer\n");
|
|
||||||
retval = -ENOMEM;
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read in first chunk of data and parse gzip header. */
|
|
||||||
fpos = offset;
|
|
||||||
ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
|
|
||||||
|
|
||||||
strm.next_in = buf;
|
|
||||||
strm.avail_in = ret;
|
|
||||||
strm.total_in = 0;
|
|
||||||
|
|
||||||
retval = -ENOEXEC;
|
|
||||||
|
|
||||||
/* Check minimum size -- gzip header */
|
|
||||||
if (ret < 10) {
|
|
||||||
DBG_FLT("binfmt_flat: file too small?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check gzip magic number */
|
|
||||||
if ((buf[0] != 037) || ((buf[1] != 0213) && (buf[1] != 0236))) {
|
|
||||||
DBG_FLT("binfmt_flat: unknown compression magic?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check gzip method */
|
|
||||||
if (buf[2] != 8) {
|
|
||||||
DBG_FLT("binfmt_flat: unknown compression method?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
/* Check gzip flags */
|
|
||||||
if ((buf[3] & ENCRYPTED) || (buf[3] & CONTINUATION) ||
|
|
||||||
(buf[3] & RESERVED)) {
|
|
||||||
DBG_FLT("binfmt_flat: unknown flags?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 10;
|
|
||||||
if (buf[3] & EXTRA_FIELD) {
|
|
||||||
ret += 2 + buf[10] + (buf[11] << 8);
|
|
||||||
if (unlikely(LBUFSIZE == ret)) {
|
|
||||||
DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (buf[3] & ORIG_NAME) {
|
|
||||||
for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
|
|
||||||
;
|
|
||||||
if (unlikely(LBUFSIZE == ret)) {
|
|
||||||
DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (buf[3] & COMMENT) {
|
|
||||||
for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
|
|
||||||
;
|
|
||||||
if (unlikely(LBUFSIZE == ret)) {
|
|
||||||
DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strm.next_in += ret;
|
|
||||||
strm.avail_in -= ret;
|
|
||||||
|
|
||||||
strm.next_out = dst;
|
|
||||||
strm.avail_out = len;
|
|
||||||
strm.total_out = 0;
|
|
||||||
|
|
||||||
if (zlib_inflateInit2(&strm, -MAX_WBITS) != Z_OK) {
|
|
||||||
DBG_FLT("binfmt_flat: zlib init failed?\n");
|
|
||||||
goto out_free_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) {
|
|
||||||
ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
|
|
||||||
if (ret <= 0)
|
|
||||||
break;
|
|
||||||
if (is_error(ret)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
len -= ret;
|
|
||||||
|
|
||||||
strm.next_in = buf;
|
|
||||||
strm.avail_in = ret;
|
|
||||||
strm.total_in = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
DBG_FLT("binfmt_flat: decompression failed (%d), %s\n",
|
|
||||||
ret, strm.msg);
|
|
||||||
goto out_zlib;
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
out_zlib:
|
|
||||||
zlib_inflateEnd(&strm);
|
|
||||||
out_free_buf:
|
|
||||||
kfree(buf);
|
|
||||||
out_free:
|
|
||||||
kfree(strm.workspace);
|
|
||||||
out:
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_BINFMT_ZFLAT */
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
@ -268,40 +115,7 @@ calc_reloc(abi_ulong r, struct lib_info *p, int curid, int internalp)
|
|||||||
abi_ulong text_len;
|
abi_ulong text_len;
|
||||||
abi_ulong start_code;
|
abi_ulong start_code;
|
||||||
|
|
||||||
#ifdef CONFIG_BINFMT_SHARED_FLAT
|
|
||||||
#error needs checking
|
|
||||||
if (r == 0)
|
|
||||||
id = curid; /* Relocs of 0 are always self referring */
|
|
||||||
else {
|
|
||||||
id = (r >> 24) & 0xff; /* Find ID for this reloc */
|
|
||||||
r &= 0x00ffffff; /* Trim ID off here */
|
|
||||||
}
|
|
||||||
if (id >= MAX_SHARED_LIBS) {
|
|
||||||
fprintf(stderr, "BINFMT_FLAT: reference 0x%x to shared library %d\n",
|
|
||||||
(unsigned) r, id);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
if (curid != id) {
|
|
||||||
if (internalp) {
|
|
||||||
fprintf(stderr, "BINFMT_FLAT: reloc address 0x%x not "
|
|
||||||
"in same module (%d != %d)\n",
|
|
||||||
(unsigned) r, curid, id);
|
|
||||||
goto failed;
|
|
||||||
} else if (!p[id].loaded && is_error(load_flat_shared_library(id, p))) {
|
|
||||||
fprintf(stderr, "BINFMT_FLAT: failed to load library %d\n", id);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
/* Check versioning information (i.e. time stamps) */
|
|
||||||
if (p[id].build_date && p[curid].build_date
|
|
||||||
&& p[curid].build_date < p[id].build_date) {
|
|
||||||
fprintf(stderr, "BINFMT_FLAT: library %d is younger than %d\n",
|
|
||||||
id, curid);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
id = 0;
|
id = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
start_brk = p[id].start_brk;
|
start_brk = p[id].start_brk;
|
||||||
start_data = p[id].start_data;
|
start_data = p[id].start_data;
|
||||||
@ -425,12 +239,10 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|||||||
if (rev == OLD_FLAT_VERSION && flat_old_ram_flag(flags))
|
if (rev == OLD_FLAT_VERSION && flat_old_ram_flag(flags))
|
||||||
flags = FLAT_FLAG_RAM;
|
flags = FLAT_FLAG_RAM;
|
||||||
|
|
||||||
#ifndef CONFIG_BINFMT_ZFLAT
|
|
||||||
if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
|
if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
|
||||||
fprintf(stderr, "Support for ZFLAT executables is not enabled\n");
|
fprintf(stderr, "ZFLAT executables are not supported\n");
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* calculate the extra space we need to map in
|
* calculate the extra space we need to map in
|
||||||
@ -483,17 +295,9 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|||||||
(int)(data_len + bss_len + stack_len), (int)datapos);
|
(int)(data_len + bss_len + stack_len), (int)datapos);
|
||||||
|
|
||||||
fpos = ntohl(hdr->data_start);
|
fpos = ntohl(hdr->data_start);
|
||||||
#ifdef CONFIG_BINFMT_ZFLAT
|
result = target_pread(bprm->src.fd, datapos,
|
||||||
if (flags & FLAT_FLAG_GZDATA) {
|
data_len + (relocs * sizeof(abi_ulong)),
|
||||||
result = decompress_exec(bprm, fpos, (char *) datapos,
|
fpos);
|
||||||
data_len + (relocs * sizeof(abi_ulong)))
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
result = target_pread(bprm->src.fd, datapos,
|
|
||||||
data_len + (relocs * sizeof(abi_ulong)),
|
|
||||||
fpos);
|
|
||||||
}
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
fprintf(stderr, "Unable to read data+bss\n");
|
fprintf(stderr, "Unable to read data+bss\n");
|
||||||
return result;
|
return result;
|
||||||
@ -515,38 +319,12 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|||||||
datapos = realdatastart + indx_len;
|
datapos = realdatastart + indx_len;
|
||||||
reloc = (textpos + ntohl(hdr->reloc_start) + indx_len);
|
reloc = (textpos + ntohl(hdr->reloc_start) + indx_len);
|
||||||
|
|
||||||
#ifdef CONFIG_BINFMT_ZFLAT
|
result = target_pread(bprm->src.fd, textpos,
|
||||||
#error code needs checking
|
text_len, 0);
|
||||||
/*
|
if (result >= 0) {
|
||||||
* load it all in and treat it like a RAM load from now on
|
result = target_pread(bprm->src.fd, datapos,
|
||||||
*/
|
data_len + (relocs * sizeof(abi_ulong)),
|
||||||
if (flags & FLAT_FLAG_GZIP) {
|
ntohl(hdr->data_start));
|
||||||
result = decompress_exec(bprm, sizeof (struct flat_hdr),
|
|
||||||
(((char *) textpos) + sizeof (struct flat_hdr)),
|
|
||||||
(text_len + data_len + (relocs * sizeof(unsigned long))
|
|
||||||
- sizeof (struct flat_hdr)),
|
|
||||||
0);
|
|
||||||
memmove((void *) datapos, (void *) realdatastart,
|
|
||||||
data_len + (relocs * sizeof(unsigned long)));
|
|
||||||
} else if (flags & FLAT_FLAG_GZDATA) {
|
|
||||||
fpos = 0;
|
|
||||||
result = bprm->file->f_op->read(bprm->file,
|
|
||||||
(char *) textpos, text_len, &fpos);
|
|
||||||
if (!is_error(result)) {
|
|
||||||
result = decompress_exec(bprm, text_len, (char *) datapos,
|
|
||||||
data_len + (relocs * sizeof(unsigned long)), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
result = target_pread(bprm->src.fd, textpos,
|
|
||||||
text_len, 0);
|
|
||||||
if (result >= 0) {
|
|
||||||
result = target_pread(bprm->src.fd, datapos,
|
|
||||||
data_len + (relocs * sizeof(abi_ulong)),
|
|
||||||
ntohl(hdr->data_start));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
fprintf(stderr, "Unable to read code+data+bss\n");
|
fprintf(stderr, "Unable to read code+data+bss\n");
|
||||||
@ -678,44 +456,6 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
#ifdef CONFIG_BINFMT_SHARED_FLAT
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load a shared library into memory. The library gets its own data
|
|
||||||
* segment (including bss) but not argv/argc/environ.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int load_flat_shared_library(int id, struct lib_info *libs)
|
|
||||||
{
|
|
||||||
struct linux_binprm bprm;
|
|
||||||
int res;
|
|
||||||
char buf[16];
|
|
||||||
|
|
||||||
/* Create the file name */
|
|
||||||
sprintf(buf, "/lib/lib%d.so", id);
|
|
||||||
|
|
||||||
/* Open the file up */
|
|
||||||
bprm.filename = buf;
|
|
||||||
bprm.file = open_exec(bprm.filename);
|
|
||||||
res = PTR_ERR(bprm.file);
|
|
||||||
if (IS_ERR(bprm.file))
|
|
||||||
return res;
|
|
||||||
|
|
||||||
res = prepare_binprm(&bprm);
|
|
||||||
|
|
||||||
if (!is_error(res)) {
|
|
||||||
res = load_flat_file(&bprm, libs, id, NULL);
|
|
||||||
}
|
|
||||||
if (bprm.file) {
|
|
||||||
allow_write_access(bprm.file);
|
|
||||||
fput(bprm.file);
|
|
||||||
bprm.file = NULL;
|
|
||||||
}
|
|
||||||
return(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_BINFMT_SHARED_FLAT */
|
|
||||||
|
|
||||||
int load_flt_binary(struct linux_binprm *bprm, struct image_info *info)
|
int load_flt_binary(struct linux_binprm *bprm, struct image_info *info)
|
||||||
{
|
{
|
||||||
struct lib_info libinfo[MAX_SHARED_LIBS];
|
struct lib_info libinfo[MAX_SHARED_LIBS];
|
||||||
@ -793,19 +533,6 @@ int load_flt_binary(struct linux_binprm *bprm, struct image_info *info)
|
|||||||
*/
|
*/
|
||||||
start_addr = libinfo[0].entry;
|
start_addr = libinfo[0].entry;
|
||||||
|
|
||||||
#ifdef CONFIG_BINFMT_SHARED_FLAT
|
|
||||||
#error here
|
|
||||||
for (i = MAX_SHARED_LIBS-1; i>0; i--) {
|
|
||||||
if (libinfo[i].loaded) {
|
|
||||||
/* Push previous first to call address */
|
|
||||||
--sp;
|
|
||||||
if (put_user_ual(start_addr, sp))
|
|
||||||
return -EFAULT;
|
|
||||||
start_addr = libinfo[i].entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Stash our initial stack pointer into the mm structure */
|
/* Stash our initial stack pointer into the mm structure */
|
||||||
info->start_code = libinfo[0].start_code;
|
info->start_code = libinfo[0].start_code;
|
||||||
info->end_code = libinfo[0].start_code + libinfo[0].text_len;
|
info->end_code = libinfo[0].start_code + libinfo[0].text_len;
|
||||||
|
Loading…
Reference in New Issue
Block a user