mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-26 21:10:42 +00:00
* SCSI fuzzing fix (Mauro)
* pre-install data files in the build directory (Akihiko) * SCSI fixes for Mac OS (Mark) -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmLO3bQUHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroNv5AgAgGe8hGOcqJSzmFgeUJ7UEaauap6E fF4zau8Xux7R6pnvPe2FeJ70AlvstFAUoU++7G3linQ+eqnFD7E18KQkfp9qX7jY xDFPJRf6JNhwDjxQ2Tp0ShOcm5HkDv4Z4cPlx0T+wfKTlUWCzNEkhVrjOhpDYnSe OldsdFjY0sUjZ1R/QNiuQ65aWwOr9gJ07KfakJQMX2YCMun6SO3kB/GtmyecTV3C uNAUIdqJLsEbR1ckdMVVmixhtzMPW2R7/vjJkxG8RXUAcDmDHkuKPhWKyZ9a7/hh CV8iMQMup6mgT8ndb5DWv551Y+C/rA1bH9U1NkaeQ9RP83CE4a6fpSMiiQ== =82zT -----END PGP SIGNATURE----- Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging * SCSI fuzzing fix (Mauro) * pre-install data files in the build directory (Akihiko) * SCSI fixes for Mac OS (Mark) # gpg: Signature made Wed 13 Jul 2022 15:59:00 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: pc-bios/s390-ccw: add -Wno-array-bounds q800: add default vendor and product information for scsi-cd devices q800: add default vendor and product information for scsi-hd devices scsi-disk: allow MODE SELECT block descriptor to set the block size scsi-disk: allow the MODE_PAGE_R_W_ERROR AWRE bit to be changeable for CDROM drives q800: implement compat_props to enable quirk_mode_page_truncated for scsi-cd devices scsi-disk: add SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED quirk for Macintosh scsi-disk: add FORMAT UNIT command q800: implement compat_props to enable quirk_mode_page_vendor_specific_apple for scsi devices scsi-disk: add SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE quirk for Macintosh q800: implement compat_props to enable quirk_mode_sense_rom_use_dbd for scsi-cd devices scsi-disk: add SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD quirk for Macintosh q800: implement compat_props to enable quirk_mode_page_apple_vendor for scsi-cd devices scsi-disk: add MODE_PAGE_APPLE_VENDOR quirk for Macintosh scsi-disk: add new quirks bitmap to SCSIDiskState meson: Prefix each element of firmware path module: Use bundle mechanism datadir: Use bundle mechanism cutils: Introduce bundle mechanism scsi/lsi53c895a: really fix use-after-free in lsi_do_msgout (CVE-2022-0216) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
285f64fcbf
@ -223,7 +223,7 @@ jobs:
|
||||
- BUILD_RC=0 && make -j${JOBS} || BUILD_RC=$?
|
||||
- |
|
||||
if [ "$BUILD_RC" -eq 0 ] ; then
|
||||
mv pc-bios/s390-ccw/*.img pc-bios/ ;
|
||||
mv pc-bios/s390-ccw/*.img qemu-bundle/usr/local/share/qemu ;
|
||||
${TEST_CMD} ;
|
||||
else
|
||||
$(exit $BUILD_RC);
|
||||
|
2
Makefile
2
Makefile
@ -216,7 +216,7 @@ qemu-%.tar.bz2:
|
||||
|
||||
distclean: clean
|
||||
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
|
||||
rm -f config-host.mak
|
||||
rm -f config-host.mak qemu-bundle
|
||||
rm -f tests/tcg/config-*.mak
|
||||
rm -f config.status
|
||||
rm -f roms/seabios/config.mak
|
||||
|
15
configure
vendored
15
configure
vendored
@ -676,6 +676,21 @@ fi
|
||||
|
||||
werror=""
|
||||
|
||||
meson_option_build_array() {
|
||||
printf '['
|
||||
(if test "$targetos" == windows; then
|
||||
IFS=\;
|
||||
else
|
||||
IFS=:
|
||||
fi
|
||||
for e in $1; do
|
||||
e=${e/'\'/'\\'}
|
||||
e=${e/\"/'\"'}
|
||||
printf '"""%s""",' "$e"
|
||||
done)
|
||||
printf ']\n'
|
||||
}
|
||||
|
||||
. $source_path/scripts/meson-buildoptions.sh
|
||||
|
||||
meson_options=
|
||||
|
@ -88,7 +88,7 @@ Windows
|
||||
|
||||
The project aims to support the two most recent versions of Windows that are
|
||||
still supported by the vendor. The minimum Windows API that is currently
|
||||
targeted is "Windows 7", so theoretically the QEMU binaries can still be run
|
||||
targeted is "Windows 8", so theoretically the QEMU binaries can still be run
|
||||
on older versions of Windows, too. However, such old versions of Windows are
|
||||
not tested anymore, so it is recommended to use one of the latest versions of
|
||||
Windows instead.
|
||||
|
@ -686,6 +686,21 @@ static void q800_init(MachineState *machine)
|
||||
}
|
||||
}
|
||||
|
||||
static GlobalProperty hw_compat_q800[] = {
|
||||
{ "scsi-hd", "quirk_mode_page_vendor_specific_apple", "on"},
|
||||
{ "scsi-hd", "vendor", " SEAGATE" },
|
||||
{ "scsi-hd", "product", " ST225N" },
|
||||
{ "scsi-hd", "ver", "1.0 " },
|
||||
{ "scsi-cd", "quirk_mode_page_apple_vendor", "on"},
|
||||
{ "scsi-cd", "quirk_mode_sense_rom_use_dbd", "on"},
|
||||
{ "scsi-cd", "quirk_mode_page_vendor_specific_apple", "on"},
|
||||
{ "scsi-cd", "quirk_mode_page_truncated", "on"},
|
||||
{ "scsi-cd", "vendor", "MATSHITA" },
|
||||
{ "scsi-cd", "product", "CD-ROM CR-8005" },
|
||||
{ "scsi-cd", "ver", "1.0k" },
|
||||
};
|
||||
static const size_t hw_compat_q800_len = G_N_ELEMENTS(hw_compat_q800);
|
||||
|
||||
static void q800_machine_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
@ -695,6 +710,7 @@ static void q800_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = 1;
|
||||
mc->block_default_type = IF_SCSI;
|
||||
mc->default_ram_id = "m68k_mac.ram";
|
||||
compat_props_add(mc->compat_props, hw_compat_q800, hw_compat_q800_len);
|
||||
}
|
||||
|
||||
static const TypeInfo q800_machine_typeinfo = {
|
||||
|
@ -1030,7 +1030,7 @@ static void lsi_do_msgout(LSIState *s)
|
||||
trace_lsi_do_msgout_abort(current_tag);
|
||||
if (current_req && current_req->req) {
|
||||
scsi_req_cancel(current_req->req);
|
||||
current_req->req = NULL;
|
||||
current_req = NULL;
|
||||
}
|
||||
lsi_disconnect(s);
|
||||
break;
|
||||
@ -1056,6 +1056,7 @@ static void lsi_do_msgout(LSIState *s)
|
||||
/* clear the current I/O process */
|
||||
if (s->current) {
|
||||
scsi_req_cancel(s->current->req);
|
||||
current_req = NULL;
|
||||
}
|
||||
|
||||
/* As the current implemented devices scsi_disk and scsi_generic
|
||||
|
@ -94,6 +94,7 @@ struct SCSIDiskState {
|
||||
uint16_t port_index;
|
||||
uint64_t max_unmap_size;
|
||||
uint64_t max_io_size;
|
||||
uint32_t quirks;
|
||||
QEMUBH *bh;
|
||||
char *version;
|
||||
char *serial;
|
||||
@ -1078,12 +1079,14 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
|
||||
int page_control)
|
||||
{
|
||||
static const int mode_sense_valid[0x3f] = {
|
||||
[MODE_PAGE_VENDOR_SPECIFIC] = (1 << TYPE_DISK) | (1 << TYPE_ROM),
|
||||
[MODE_PAGE_HD_GEOMETRY] = (1 << TYPE_DISK),
|
||||
[MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1 << TYPE_DISK),
|
||||
[MODE_PAGE_CACHING] = (1 << TYPE_DISK) | (1 << TYPE_ROM),
|
||||
[MODE_PAGE_R_W_ERROR] = (1 << TYPE_DISK) | (1 << TYPE_ROM),
|
||||
[MODE_PAGE_AUDIO_CTL] = (1 << TYPE_ROM),
|
||||
[MODE_PAGE_CAPABILITIES] = (1 << TYPE_ROM),
|
||||
[MODE_PAGE_APPLE_VENDOR] = (1 << TYPE_ROM),
|
||||
};
|
||||
|
||||
uint8_t *p = *p_outbuf + 2;
|
||||
@ -1185,6 +1188,10 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
|
||||
case MODE_PAGE_R_W_ERROR:
|
||||
length = 10;
|
||||
if (page_control == 1) { /* Changeable Values */
|
||||
if (s->qdev.type == TYPE_ROM) {
|
||||
/* Automatic Write Reallocation Enabled */
|
||||
p[0] = 0x80;
|
||||
}
|
||||
break;
|
||||
}
|
||||
p[0] = 0x80; /* Automatic Write Reallocation Enabled */
|
||||
@ -1228,6 +1235,36 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
|
||||
p[19] = (16 * 176) & 0xff;
|
||||
break;
|
||||
|
||||
case MODE_PAGE_APPLE_VENDOR:
|
||||
if (s->quirks & (1 << SCSI_DISK_QUIRK_MODE_PAGE_APPLE_VENDOR)) {
|
||||
length = 0x1e;
|
||||
if (page_control == 1) { /* Changeable Values */
|
||||
break;
|
||||
}
|
||||
|
||||
memset(p, 0, length);
|
||||
strcpy((char *)p + 8, "APPLE COMPUTER, INC ");
|
||||
break;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
case MODE_PAGE_VENDOR_SPECIFIC:
|
||||
if (s->qdev.type == TYPE_DISK && (s->quirks &
|
||||
(1 << SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE))) {
|
||||
length = 0x2;
|
||||
if (page_control == 1) { /* Changeable Values */
|
||||
p[0] = 0xff;
|
||||
p[1] = 0xff;
|
||||
break;
|
||||
}
|
||||
p[0] = 0;
|
||||
p[1] = 0;
|
||||
break;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -1263,10 +1300,27 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
|
||||
dev_specific_param |= 0x80; /* Readonly. */
|
||||
}
|
||||
} else {
|
||||
/* MMC prescribes that CD/DVD drives have no block descriptors,
|
||||
* and defines no device-specific parameter. */
|
||||
dev_specific_param = 0x00;
|
||||
dbd = true;
|
||||
if (s->quirks & (1 << SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD)) {
|
||||
/* Use DBD from the request... */
|
||||
dev_specific_param = 0x00;
|
||||
|
||||
/*
|
||||
* ... unless we receive a request for MODE_PAGE_APPLE_VENDOR
|
||||
* which should never return a block descriptor even though DBD is
|
||||
* not set, otherwise CDROM detection fails in MacOS
|
||||
*/
|
||||
if (s->quirks & (1 << SCSI_DISK_QUIRK_MODE_PAGE_APPLE_VENDOR) &&
|
||||
page == MODE_PAGE_APPLE_VENDOR) {
|
||||
dbd = true;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* MMC prescribes that CD/DVD drives have no block descriptors,
|
||||
* and defines no device-specific parameter.
|
||||
*/
|
||||
dev_specific_param = 0x00;
|
||||
dbd = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->req.cmd.buf[0] == MODE_SENSE) {
|
||||
@ -1502,7 +1556,10 @@ static int mode_select_pages(SCSIDiskReq *r, uint8_t *p, int len, bool change)
|
||||
goto invalid_param;
|
||||
}
|
||||
if (page_len > len) {
|
||||
goto invalid_param_len;
|
||||
if (!(s->quirks & SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED)) {
|
||||
goto invalid_param_len;
|
||||
}
|
||||
trace_scsi_disk_mode_select_page_truncated(page, page_len, len);
|
||||
}
|
||||
|
||||
if (!change) {
|
||||
@ -1537,9 +1594,12 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
|
||||
int bd_len;
|
||||
int pass;
|
||||
|
||||
/* We only support PF=1, SP=0. */
|
||||
if ((r->req.cmd.buf[1] & 0x11) != 0x10) {
|
||||
goto invalid_field;
|
||||
if (!(s->quirks &
|
||||
(1 << SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE))) {
|
||||
/* We only support PF=1, SP=0. */
|
||||
goto invalid_field;
|
||||
}
|
||||
}
|
||||
|
||||
if (len < hdr_len) {
|
||||
@ -1556,6 +1616,12 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
|
||||
goto invalid_param;
|
||||
}
|
||||
|
||||
/* Allow changing the block size */
|
||||
if (bd_len && p[6] != (s->qdev.blocksize >> 8)) {
|
||||
s->qdev.blocksize = p[6] << 8;
|
||||
trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize);
|
||||
}
|
||||
|
||||
len -= bd_len;
|
||||
p += bd_len;
|
||||
|
||||
@ -2127,6 +2193,9 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
|
||||
trace_scsi_disk_emulate_command_WRITE_SAME(
|
||||
req->cmd.buf[0] == WRITE_SAME_10 ? 10 : 16, r->req.cmd.xfer);
|
||||
break;
|
||||
case FORMAT_UNIT:
|
||||
trace_scsi_disk_emulate_command_FORMAT_UNIT(r->req.cmd.xfer);
|
||||
break;
|
||||
default:
|
||||
trace_scsi_disk_emulate_command_UNKNOWN(buf[0],
|
||||
scsi_command_name(buf[0]));
|
||||
@ -2532,6 +2601,7 @@ static const SCSIReqOps *const scsi_disk_reqops_dispatch[256] = {
|
||||
[VERIFY_10] = &scsi_disk_emulate_reqops,
|
||||
[VERIFY_12] = &scsi_disk_emulate_reqops,
|
||||
[VERIFY_16] = &scsi_disk_emulate_reqops,
|
||||
[FORMAT_UNIT] = &scsi_disk_emulate_reqops,
|
||||
|
||||
[READ_6] = &scsi_disk_dma_reqops,
|
||||
[READ_10] = &scsi_disk_dma_reqops,
|
||||
@ -3036,6 +3106,9 @@ static Property scsi_hd_properties[] = {
|
||||
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
|
||||
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
|
||||
5),
|
||||
DEFINE_PROP_BIT("quirk_mode_page_vendor_specific_apple", SCSIDiskState,
|
||||
quirks, SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE,
|
||||
0),
|
||||
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
@ -3084,6 +3157,15 @@ static Property scsi_cd_properties[] = {
|
||||
DEFAULT_MAX_IO_SIZE),
|
||||
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
|
||||
5),
|
||||
DEFINE_PROP_BIT("quirk_mode_page_apple_vendor", SCSIDiskState, quirks,
|
||||
SCSI_DISK_QUIRK_MODE_PAGE_APPLE_VENDOR, 0),
|
||||
DEFINE_PROP_BIT("quirk_mode_sense_rom_use_dbd", SCSIDiskState, quirks,
|
||||
SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD, 0),
|
||||
DEFINE_PROP_BIT("quirk_mode_page_vendor_specific_apple", SCSIDiskState,
|
||||
quirks, SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE,
|
||||
0),
|
||||
DEFINE_PROP_BIT("quirk_mode_page_truncated", SCSIDiskState, quirks,
|
||||
SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -334,10 +334,13 @@ scsi_disk_emulate_command_UNMAP(size_t xfer) "Unmap (len %zd)"
|
||||
scsi_disk_emulate_command_VERIFY(int bytchk) "Verify (bytchk %d)"
|
||||
scsi_disk_emulate_command_WRITE_SAME(int cmd, size_t xfer) "WRITE SAME %d (len %zd)"
|
||||
scsi_disk_emulate_command_UNKNOWN(int cmd, const char *name) "Unknown SCSI command (0x%2.2x=%s)"
|
||||
scsi_disk_emulate_command_FORMAT_UNIT(size_t xfer) "Format Unit (len %zu)"
|
||||
scsi_disk_dma_command_READ(uint64_t lba, uint32_t len) "Read (sector %" PRId64 ", count %u)"
|
||||
scsi_disk_dma_command_WRITE(const char *cmd, uint64_t lba, int len) "Write %s(sector %" PRId64 ", count %u)"
|
||||
scsi_disk_new_request(uint32_t lun, uint32_t tag, const char *line) "Command: lun=%d tag=0x%x data=%s"
|
||||
scsi_disk_aio_sgio_command(uint32_t tag, uint8_t cmd, uint64_t lba, int len, uint32_t timeout) "disk aio sgio: tag=0x%x cmd=0x%x (sector %" PRId64 ", count %d) timeout=%u"
|
||||
scsi_disk_mode_select_page_truncated(int page, int len, int page_len) "page %d expected length %d but received length %d"
|
||||
scsi_disk_mode_select_set_blocksize(int blocksize) "set block size to %d"
|
||||
|
||||
# scsi-generic.c
|
||||
scsi_generic_command_complete_noio(void *req, uint32_t tag, int statuc) "Command complete %p tag=0x%x status=%d"
|
||||
|
@ -226,4 +226,10 @@ SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int target, int lun);
|
||||
/* scsi-generic.c. */
|
||||
extern const SCSIReqOps scsi_generic_req_ops;
|
||||
|
||||
/* scsi-disk.c */
|
||||
#define SCSI_DISK_QUIRK_MODE_PAGE_APPLE_VENDOR 0
|
||||
#define SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD 1
|
||||
#define SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE 2
|
||||
#define SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED 3
|
||||
|
||||
#endif
|
||||
|
@ -224,9 +224,21 @@ const char *qemu_get_exec_dir(void);
|
||||
* @dir: the directory (typically a `CONFIG_*DIR` variable) to be relocated.
|
||||
*
|
||||
* Returns a path for @dir that uses the directory of the running executable
|
||||
* as the prefix. For example, if `bindir` is `/usr/bin` and @dir is
|
||||
* `/usr/share/qemu`, the function will append `../share/qemu` to the
|
||||
* directory that contains the running executable and return the result.
|
||||
* as the prefix.
|
||||
*
|
||||
* When a directory named `qemu-bundle` exists in the directory of the running
|
||||
* executable, the path to the directory will be prepended to @dir. For
|
||||
* example, if the directory of the running executable is `/qemu/build` @dir
|
||||
* is `/usr/share/qemu`, the result will be
|
||||
* `/qemu/build/qemu-bundle/usr/share/qemu`. The directory is expected to exist
|
||||
* in the build tree.
|
||||
*
|
||||
* Otherwise, the directory of the running executable will be used as the
|
||||
* prefix and it appends the relative path from `bindir` to @dir. For example,
|
||||
* if the directory of the running executable is `/opt/qemu/bin`, `bindir` is
|
||||
* `/usr/bin` and @dir is `/usr/share/qemu`, the result will be
|
||||
* `/opt/qemu/bin/../share/qemu`.
|
||||
*
|
||||
* The returned string should be freed by the caller.
|
||||
*/
|
||||
char *get_relocated_path(const char *dir);
|
||||
|
@ -225,6 +225,7 @@
|
||||
#define TYPE_NO_LUN 0x7f
|
||||
|
||||
/* Mode page codes for mode sense/set */
|
||||
#define MODE_PAGE_VENDOR_SPECIFIC 0x00
|
||||
#define MODE_PAGE_R_W_ERROR 0x01
|
||||
#define MODE_PAGE_HD_GEOMETRY 0x04
|
||||
#define MODE_PAGE_FLEXIBLE_DISK_GEOMETRY 0x05
|
||||
@ -234,6 +235,7 @@
|
||||
#define MODE_PAGE_FAULT_FAIL 0x1c
|
||||
#define MODE_PAGE_TO_PROTECT 0x1d
|
||||
#define MODE_PAGE_CAPABILITIES 0x2a
|
||||
#define MODE_PAGE_APPLE_VENDOR 0x30
|
||||
#define MODE_PAGE_ALLS 0x3f
|
||||
/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
|
||||
* of MODE_PAGE_SENSE_POWER */
|
||||
|
15
meson.build
15
meson.build
@ -7,6 +7,8 @@ add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
|
||||
add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
|
||||
add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
|
||||
|
||||
meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
|
||||
|
||||
not_found = dependency('', required: false)
|
||||
keyval = import('keyval')
|
||||
ss = import('sourceset')
|
||||
@ -356,10 +358,12 @@ nvmm =not_found
|
||||
hvf = not_found
|
||||
midl = not_found
|
||||
widl = not_found
|
||||
pathcch = not_found
|
||||
host_dsosuf = '.so'
|
||||
if targetos == 'windows'
|
||||
midl = find_program('midl', required: false)
|
||||
widl = find_program('widl', required: false)
|
||||
pathcch = cc.find_library('pathcch')
|
||||
socket = cc.find_library('ws2_32')
|
||||
winmm = cc.find_library('winmm')
|
||||
|
||||
@ -1715,7 +1719,13 @@ config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
|
||||
config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
|
||||
config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
|
||||
config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
|
||||
config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('prefix') / get_option('qemu_firmwarepath'))
|
||||
|
||||
qemu_firmwarepath = ''
|
||||
foreach k : get_option('qemu_firmwarepath')
|
||||
qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
|
||||
endforeach
|
||||
config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
|
||||
|
||||
config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
|
||||
config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
|
||||
config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
|
||||
@ -3680,7 +3690,8 @@ endif
|
||||
summary_info = {}
|
||||
summary_info += {'Install prefix': get_option('prefix')}
|
||||
summary_info += {'BIOS directory': qemu_datadir}
|
||||
summary_info += {'firmware path': get_option('prefix') / get_option('qemu_firmwarepath')}
|
||||
pathsep = targetos == 'windows' ? ';' : ':'
|
||||
summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
|
||||
summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
|
||||
summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
|
||||
summary_info += {'module directory': qemu_moddir}
|
||||
|
@ -6,7 +6,7 @@ option('qemu_suffix', type : 'string', value: 'qemu',
|
||||
description: 'Suffix for QEMU data/modules/config directories (can be empty)')
|
||||
option('docdir', type : 'string', value : 'share/doc',
|
||||
description: 'Base directory for documentation installation (can be empty)')
|
||||
option('qemu_firmwarepath', type : 'string', value : 'share/qemu-firmware',
|
||||
option('qemu_firmwarepath', type : 'array', value : ['share/qemu-firmware'],
|
||||
description: 'search PATH for firmware files')
|
||||
option('pkgversion', type : 'string', value : '',
|
||||
description: 'use specified string as sub-version of the package')
|
||||
|
@ -40,9 +40,9 @@ else
|
||||
endif
|
||||
cp = find_program('cp')
|
||||
|
||||
t = []
|
||||
foreach km, args: keymaps
|
||||
if native_qemu_keymap.found()
|
||||
if native_qemu_keymap.found()
|
||||
t = []
|
||||
foreach km, args: keymaps
|
||||
# generate with qemu-kvm
|
||||
t += custom_target(km,
|
||||
build_by_default: true,
|
||||
@ -50,20 +50,11 @@ foreach km, args: keymaps
|
||||
command: [native_qemu_keymap, '-f', '@OUTPUT@', args.split()],
|
||||
install: true,
|
||||
install_dir: qemu_datadir / 'keymaps')
|
||||
else
|
||||
# copy from source tree
|
||||
t += custom_target(km,
|
||||
build_by_default: true,
|
||||
input: km,
|
||||
output: km,
|
||||
command: [cp, '@INPUT@', '@OUTPUT@'],
|
||||
install: true,
|
||||
install_dir: qemu_datadir / 'keymaps')
|
||||
endif
|
||||
endforeach
|
||||
endforeach
|
||||
|
||||
if native_qemu_keymap.found()
|
||||
alias_target('update-keymaps', t)
|
||||
else
|
||||
install_data(keymaps.keys(), install_dir: qemu_datadir / 'keymaps')
|
||||
endif
|
||||
|
||||
install_data(['sl', 'sv'], install_dir: qemu_datadir / 'keymaps')
|
||||
|
@ -85,16 +85,9 @@ blobs = [
|
||||
'vof-nvram.bin',
|
||||
]
|
||||
|
||||
ln_s = [find_program('ln', required: true), '-sf']
|
||||
foreach f : blobs
|
||||
roms += custom_target(f,
|
||||
build_by_default: have_system,
|
||||
output: f,
|
||||
input: files('meson.build'), # dummy input
|
||||
install: get_option('install_blobs'),
|
||||
install_dir: qemu_datadir,
|
||||
command: [ ln_s, meson.project_source_root() / 'pc-bios' / f, '@OUTPUT@' ])
|
||||
endforeach
|
||||
if get_option('install_blobs')
|
||||
install_data(blobs, install_dir: qemu_datadir)
|
||||
endif
|
||||
|
||||
subdir('descriptors')
|
||||
subdir('keymaps')
|
||||
|
@ -35,6 +35,7 @@ EXTRA_CFLAGS += $(call cc-option,-Werror $(EXTRA_CFLAGS),-Wno-stringop-overflow)
|
||||
EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE
|
||||
EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables
|
||||
EXTRA_CFLAGS += $(call cc-option, $(EXTRA_CFLAGS), -fno-stack-protector)
|
||||
EXTRA_CFLAGS += $(call cc-option, $(EXTRA_CFLAGS), -Wno-array-bounds)
|
||||
EXTRA_CFLAGS += -msoft-float
|
||||
EXTRA_CFLAGS += $(call cc-option, $(EXTRA_CFLAGS),-march=z900,-march=z10)
|
||||
EXTRA_CFLAGS += -std=gnu99
|
||||
|
@ -156,7 +156,7 @@ def cli_metavar(opt):
|
||||
if opt["type"] == "string":
|
||||
return "VALUE"
|
||||
if opt["type"] == "array":
|
||||
return "CHOICES"
|
||||
return "CHOICES" if "choices" in opt else "VALUES"
|
||||
return "CHOICE"
|
||||
|
||||
|
||||
@ -199,7 +199,10 @@ def print_parse(options):
|
||||
key = cli_option(opt)
|
||||
name = opt["name"]
|
||||
if require_arg(opt):
|
||||
print(f' --{key}=*) quote_sh "-D{name}=$2" ;;')
|
||||
if opt["type"] == "array" and not "choices" in opt:
|
||||
print(f' --{key}=*) quote_sh "-D{name}=$(meson_option_build_array $2)" ;;')
|
||||
else:
|
||||
print(f' --{key}=*) quote_sh "-D{name}=$2" ;;')
|
||||
elif opt["type"] == "boolean":
|
||||
print(f' --enable-{key}) printf "%s" -D{name}=true ;;')
|
||||
print(f' --disable-{key}) printf "%s" -D{name}=false ;;')
|
||||
|
@ -42,7 +42,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' --enable-trace-backends=CHOICES'
|
||||
printf "%s\n" ' Set available tracing backends [log] (choices:'
|
||||
printf "%s\n" ' dtrace/ftrace/log/nop/simple/syslog/ust)'
|
||||
printf "%s\n" ' --firmwarepath=VALUE search PATH for firmware files [share/qemu-firmware]'
|
||||
printf "%s\n" ' --firmwarepath=VALUES search PATH for firmware files [share/qemu-firmware]'
|
||||
printf "%s\n" ' --iasl=VALUE Path to ACPI disassembler'
|
||||
printf "%s\n" ' --includedir=VALUE Header file directory [include]'
|
||||
printf "%s\n" ' --interp-prefix=VALUE where to find shared libraries etc., use %M for'
|
||||
@ -363,7 +363,7 @@ _meson_option_parse() {
|
||||
--disable-qcow1) printf "%s" -Dqcow1=disabled ;;
|
||||
--enable-qed) printf "%s" -Dqed=enabled ;;
|
||||
--disable-qed) printf "%s" -Dqed=disabled ;;
|
||||
--firmwarepath=*) quote_sh "-Dqemu_firmwarepath=$2" ;;
|
||||
--firmwarepath=*) quote_sh "-Dqemu_firmwarepath=$(meson_option_build_array $2)" ;;
|
||||
--enable-qga-vss) printf "%s" -Dqga_vss=enabled ;;
|
||||
--disable-qga-vss) printf "%s" -Dqga_vss=disabled ;;
|
||||
--enable-qom-cast-debug) printf "%s" -Dqom_cast_debug=true ;;
|
||||
|
@ -64,7 +64,7 @@ mkdir -p "$DEST_DIR/lib/" # Copy the shared libraries here
|
||||
|
||||
# Build once to get the list of dynamic lib paths, and copy them over
|
||||
../configure --disable-werror --cc="$CC" --cxx="$CXX" --enable-fuzzing \
|
||||
--prefix="$DEST_DIR" --bindir="$DEST_DIR" --datadir="$DEST_DIR/data/" \
|
||||
--prefix="/opt/qemu-oss-fuzz" \
|
||||
--extra-cflags="$EXTRA_CFLAGS" --target-list="i386-softmmu"
|
||||
|
||||
if ! make "-j$(nproc)" qemu-fuzz-i386; then
|
||||
@ -81,14 +81,14 @@ if [ "$GITLAB_CI" != "true" ]; then
|
||||
|
||||
# Build a second time to build the final binary with correct rpath
|
||||
../configure --disable-werror --cc="$CC" --cxx="$CXX" --enable-fuzzing \
|
||||
--prefix="$DEST_DIR" --bindir="$DEST_DIR" --datadir="$DEST_DIR/data/" \
|
||||
--prefix="/opt/qemu-oss-fuzz" \
|
||||
--extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="-Wl,-rpath,\$ORIGIN/lib" \
|
||||
--target-list="i386-softmmu"
|
||||
make "-j$(nproc)" qemu-fuzz-i386 V=1
|
||||
fi
|
||||
|
||||
# Copy over the datadir
|
||||
cp -r ../pc-bios/ "$DEST_DIR/pc-bios"
|
||||
# Prepare a preinstalled tree
|
||||
make install DESTDIR=$DEST_DIR/qemu-bundle
|
||||
|
||||
targets=$(./qemu-fuzz-i386 | awk '$1 ~ /\*/ {print $2}')
|
||||
base_copy="$DEST_DIR/qemu-fuzz-i386-target-$(echo "$targets" | head -n 1)"
|
||||
|
33
scripts/symlink-install-tree.py
Normal file
33
scripts/symlink-install-tree.py
Normal file
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from pathlib import PurePath
|
||||
import errno
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def destdir_join(d1: str, d2: str) -> str:
|
||||
if not d1:
|
||||
return d2
|
||||
# c:\destdir + c:\prefix must produce c:\destdir\prefix
|
||||
return str(PurePath(d1, *PurePath(d2).parts[1:]))
|
||||
|
||||
introspect = os.environ.get('MESONINTROSPECT')
|
||||
out = subprocess.run([*introspect.split(' '), '--installed'],
|
||||
stdout=subprocess.PIPE, check=True).stdout
|
||||
for source, dest in json.loads(out).items():
|
||||
assert os.path.isabs(source)
|
||||
bundle_dest = destdir_join('qemu-bundle', dest)
|
||||
path = os.path.dirname(bundle_dest)
|
||||
try:
|
||||
os.makedirs(path, exist_ok=True)
|
||||
except BaseException as e:
|
||||
print(f'error making directory {path}', file=sys.stderr)
|
||||
raise e
|
||||
try:
|
||||
os.symlink(source, bundle_dest)
|
||||
except BaseException as e:
|
||||
if not isinstance(e, OSError) or e.errno != errno.EEXIST:
|
||||
print(f'error making symbolic link {dest}', file=sys.stderr)
|
||||
raise e
|
@ -83,40 +83,22 @@ void qemu_add_data_dir(char *path)
|
||||
data_dir[data_dir_idx++] = path;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a likely location for support files using the location of the binary.
|
||||
* When running from the build tree this will be "$bindir/pc-bios".
|
||||
* Otherwise, this is CONFIG_QEMU_DATADIR (possibly relocated).
|
||||
*
|
||||
* The caller must use g_free() to free the returned data when it is
|
||||
* no longer required.
|
||||
*/
|
||||
static char *find_datadir(void)
|
||||
{
|
||||
g_autofree char *dir = NULL;
|
||||
|
||||
dir = g_build_filename(qemu_get_exec_dir(), "pc-bios", NULL);
|
||||
if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
|
||||
return g_steal_pointer(&dir);
|
||||
}
|
||||
|
||||
return get_relocated_path(CONFIG_QEMU_DATADIR);
|
||||
}
|
||||
|
||||
void qemu_add_default_firmwarepath(void)
|
||||
{
|
||||
char **dirs;
|
||||
static const char * const dirs[] = {
|
||||
CONFIG_QEMU_FIRMWAREPATH
|
||||
NULL
|
||||
};
|
||||
|
||||
size_t i;
|
||||
|
||||
/* add configured firmware directories */
|
||||
dirs = g_strsplit(CONFIG_QEMU_FIRMWAREPATH, G_SEARCHPATH_SEPARATOR_S, 0);
|
||||
for (i = 0; dirs[i] != NULL; i++) {
|
||||
qemu_add_data_dir(get_relocated_path(dirs[i]));
|
||||
}
|
||||
g_strfreev(dirs);
|
||||
|
||||
/* try to find datadir relative to the executable path */
|
||||
qemu_add_data_dir(find_datadir());
|
||||
qemu_add_data_dir(get_relocated_path(CONFIG_QEMU_DATADIR));
|
||||
}
|
||||
|
||||
void qemu_list_data_dirs(void)
|
||||
|
@ -8,6 +8,79 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "libqtest.h"
|
||||
|
||||
/*
|
||||
* This used to trigger a UAF in lsi_do_msgout()
|
||||
* https://gitlab.com/qemu-project/qemu/-/issues/972
|
||||
*/
|
||||
static void test_lsi_do_msgout_cancel_req(void)
|
||||
{
|
||||
QTestState *s;
|
||||
|
||||
if (sizeof(void *) == 4) {
|
||||
g_test_skip("memory size too big for 32-bit build");
|
||||
return;
|
||||
}
|
||||
|
||||
s = qtest_init("-M q35 -m 4G -display none -nodefaults "
|
||||
"-device lsi53c895a,id=scsi "
|
||||
"-device scsi-hd,drive=disk0 "
|
||||
"-drive file=null-co://,id=disk0,if=none,format=raw");
|
||||
|
||||
qtest_outl(s, 0xcf8, 0x80000810);
|
||||
qtest_outl(s, 0xcf8, 0xc000);
|
||||
qtest_outl(s, 0xcf8, 0x80000810);
|
||||
qtest_outw(s, 0xcfc, 0x7);
|
||||
qtest_outl(s, 0xcf8, 0x80000810);
|
||||
qtest_outl(s, 0xcfc, 0xc000);
|
||||
qtest_outl(s, 0xcf8, 0x80000804);
|
||||
qtest_outw(s, 0xcfc, 0x05);
|
||||
qtest_writeb(s, 0x69736c10, 0x08);
|
||||
qtest_writeb(s, 0x69736c13, 0x58);
|
||||
qtest_writeb(s, 0x69736c1a, 0x01);
|
||||
qtest_writeb(s, 0x69736c1b, 0x06);
|
||||
qtest_writeb(s, 0x69736c22, 0x01);
|
||||
qtest_writeb(s, 0x69736c23, 0x07);
|
||||
qtest_writeb(s, 0x69736c2b, 0x02);
|
||||
qtest_writeb(s, 0x69736c48, 0x08);
|
||||
qtest_writeb(s, 0x69736c4b, 0x58);
|
||||
qtest_writeb(s, 0x69736c52, 0x04);
|
||||
qtest_writeb(s, 0x69736c53, 0x06);
|
||||
qtest_writeb(s, 0x69736c5b, 0x02);
|
||||
qtest_outl(s, 0xc02d, 0x697300);
|
||||
qtest_writeb(s, 0x5a554662, 0x01);
|
||||
qtest_writeb(s, 0x5a554663, 0x07);
|
||||
qtest_writeb(s, 0x5a55466a, 0x10);
|
||||
qtest_writeb(s, 0x5a55466b, 0x22);
|
||||
qtest_writeb(s, 0x5a55466c, 0x5a);
|
||||
qtest_writeb(s, 0x5a55466d, 0x5a);
|
||||
qtest_writeb(s, 0x5a55466e, 0x34);
|
||||
qtest_writeb(s, 0x5a55466f, 0x5a);
|
||||
qtest_writeb(s, 0x5a345a5a, 0x77);
|
||||
qtest_writeb(s, 0x5a345a5b, 0x55);
|
||||
qtest_writeb(s, 0x5a345a5c, 0x51);
|
||||
qtest_writeb(s, 0x5a345a5d, 0x27);
|
||||
qtest_writeb(s, 0x27515577, 0x41);
|
||||
qtest_outl(s, 0xc02d, 0x5a5500);
|
||||
qtest_writeb(s, 0x364001d0, 0x08);
|
||||
qtest_writeb(s, 0x364001d3, 0x58);
|
||||
qtest_writeb(s, 0x364001da, 0x01);
|
||||
qtest_writeb(s, 0x364001db, 0x26);
|
||||
qtest_writeb(s, 0x364001dc, 0x0d);
|
||||
qtest_writeb(s, 0x364001dd, 0xae);
|
||||
qtest_writeb(s, 0x364001de, 0x41);
|
||||
qtest_writeb(s, 0x364001df, 0x5a);
|
||||
qtest_writeb(s, 0x5a41ae0d, 0xf8);
|
||||
qtest_writeb(s, 0x5a41ae0e, 0x36);
|
||||
qtest_writeb(s, 0x5a41ae0f, 0xd7);
|
||||
qtest_writeb(s, 0x5a41ae10, 0x36);
|
||||
qtest_writeb(s, 0x36d736f8, 0x0c);
|
||||
qtest_writeb(s, 0x36d736f9, 0x80);
|
||||
qtest_writeb(s, 0x36d736fa, 0x0d);
|
||||
qtest_outl(s, 0xc02d, 0x364000);
|
||||
|
||||
qtest_quit(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* This used to trigger the assert in lsi_do_dma()
|
||||
* https://bugs.launchpad.net/qemu/+bug/697510
|
||||
@ -44,5 +117,8 @@ int main(int argc, char **argv)
|
||||
qtest_add_func("fuzz/lsi53c895a/lsi_do_dma_empty_queue",
|
||||
test_lsi_do_dma_empty_queue);
|
||||
|
||||
qtest_add_func("fuzz/lsi53c895a/lsi_do_msgout_cancel_req",
|
||||
test_lsi_do_msgout_cancel_req);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
@ -158,8 +158,6 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
|
||||
{
|
||||
|
||||
char *target_name;
|
||||
const char *bindir;
|
||||
char *datadir;
|
||||
GString *cmd_line;
|
||||
gchar *pretty_cmd_line;
|
||||
bool serialize = false;
|
||||
@ -174,22 +172,6 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
|
||||
target_name = strstr(**argv, "-target-");
|
||||
if (target_name) { /* The binary name specifies the target */
|
||||
target_name += strlen("-target-");
|
||||
/*
|
||||
* With oss-fuzz, the executable is kept in the root of a directory (we
|
||||
* cannot assume the path). All data (including bios binaries) must be
|
||||
* in the same dir, or a subdir. Thus, we cannot place the pc-bios so
|
||||
* that it would be in exec_dir/../pc-bios.
|
||||
* As a workaround, oss-fuzz allows us to use argv[0] to get the
|
||||
* location of the executable. Using this we add exec_dir/pc-bios to
|
||||
* the datadirs.
|
||||
*/
|
||||
bindir = qemu_get_exec_dir();
|
||||
datadir = g_build_filename(bindir, "pc-bios", NULL);
|
||||
if (g_file_test(datadir, G_FILE_TEST_IS_DIR)) {
|
||||
qemu_add_data_dir(datadir);
|
||||
} else {
|
||||
g_free(datadir);
|
||||
}
|
||||
} else if (*argc > 1) { /* The target is specified as an argument */
|
||||
target_name = (*argv)[1];
|
||||
if (!strstr(target_name, "--fuzz-target=")) {
|
||||
|
@ -35,6 +35,11 @@
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <pathcch.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "qemu/ctype.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/error-report.h"
|
||||
@ -1074,31 +1079,52 @@ char *get_relocated_path(const char *dir)
|
||||
|
||||
/* Fail if qemu_init_exec_dir was not called. */
|
||||
assert(exec_dir[0]);
|
||||
if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
|
||||
return g_strdup(dir);
|
||||
}
|
||||
|
||||
result = g_string_new(exec_dir);
|
||||
g_string_append(result, "/qemu-bundle");
|
||||
if (access(result->str, R_OK) == 0) {
|
||||
#ifdef G_OS_WIN32
|
||||
size_t size = mbsrtowcs(NULL, &dir, 0, &(mbstate_t){0}) + 1;
|
||||
PWSTR wdir = g_new(WCHAR, size);
|
||||
mbsrtowcs(wdir, &dir, size, &(mbstate_t){0});
|
||||
|
||||
/* Advance over common components. */
|
||||
len_dir = len_bindir = prefix_len;
|
||||
do {
|
||||
dir += len_dir;
|
||||
bindir += len_bindir;
|
||||
dir = next_component(dir, &len_dir);
|
||||
bindir = next_component(bindir, &len_bindir);
|
||||
} while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
|
||||
PCWSTR wdir_skipped_root;
|
||||
PathCchSkipRoot(wdir, &wdir_skipped_root);
|
||||
|
||||
/* Ascend from bindir to the common prefix with dir. */
|
||||
while (len_bindir) {
|
||||
bindir += len_bindir;
|
||||
g_string_append(result, "/..");
|
||||
bindir = next_component(bindir, &len_bindir);
|
||||
size = wcsrtombs(NULL, &wdir_skipped_root, 0, &(mbstate_t){0});
|
||||
char *cursor = result->str + result->len;
|
||||
g_string_set_size(result, result->len + size);
|
||||
wcsrtombs(cursor, &wdir_skipped_root, size + 1, &(mbstate_t){0});
|
||||
g_free(wdir);
|
||||
#else
|
||||
g_string_append(result, dir);
|
||||
#endif
|
||||
} else if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
|
||||
g_string_assign(result, dir);
|
||||
} else {
|
||||
g_string_assign(result, exec_dir);
|
||||
|
||||
/* Advance over common components. */
|
||||
len_dir = len_bindir = prefix_len;
|
||||
do {
|
||||
dir += len_dir;
|
||||
bindir += len_bindir;
|
||||
dir = next_component(dir, &len_dir);
|
||||
bindir = next_component(bindir, &len_bindir);
|
||||
} while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
|
||||
|
||||
/* Ascend from bindir to the common prefix with dir. */
|
||||
while (len_bindir) {
|
||||
bindir += len_bindir;
|
||||
g_string_append(result, "/..");
|
||||
bindir = next_component(bindir, &len_bindir);
|
||||
}
|
||||
|
||||
if (*dir) {
|
||||
assert(G_IS_DIR_SEPARATOR(dir[-1]));
|
||||
g_string_append(result, dir - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (*dir) {
|
||||
assert(G_IS_DIR_SEPARATOR(dir[-1]));
|
||||
g_string_append(result, dir - 1);
|
||||
}
|
||||
return g_string_free(result, false);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ util_ss.add(when: 'CONFIG_WIN32', if_true: files('event_notifier-win32.c'))
|
||||
util_ss.add(when: 'CONFIG_WIN32', if_true: files('oslib-win32.c'))
|
||||
util_ss.add(when: 'CONFIG_WIN32', if_true: files('qemu-thread-win32.c'))
|
||||
util_ss.add(when: 'CONFIG_WIN32', if_true: winmm)
|
||||
util_ss.add(when: 'CONFIG_WIN32', if_true: pathcch)
|
||||
util_ss.add(files('envlist.c', 'path.c', 'module.c'))
|
||||
util_ss.add(files('host-utils.c'))
|
||||
util_ss.add(files('bitmap.c', 'bitops.c'))
|
||||
|
@ -274,7 +274,6 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
|
||||
dirs[n_dirs++] = g_strdup_printf("%s", search_dir);
|
||||
}
|
||||
dirs[n_dirs++] = get_relocated_path(CONFIG_QEMU_MODDIR);
|
||||
dirs[n_dirs++] = g_strdup(qemu_get_exec_dir());
|
||||
|
||||
#ifdef CONFIG_MODULE_UPGRADES
|
||||
version_dir = g_strcanon(g_strdup(QEMU_PKGVERSION),
|
||||
|
Loading…
Reference in New Issue
Block a user