Skip to content

Update Ubuntu (and therefore Qemu) Version #557

@Alexhuszagh

Description

@Alexhuszagh

Currently, on images provided by cross v0.2.1, we get the following after loading into the image:

Cross Information:

$ cross --version
cross 0.2.1
cargo 1.51.0 (43b129a20 2021-03-16)

Image Information

$ $ docker images
REPOSITORY           TAG                                     IMAGE ID       CREATED         SIZE
rustembedded/cross   powerpc-unknown-linux-gnu-0.2.1         e18a73ede16f   10 months ago   752MB
$ docker run -it e18a73ede16f /bin/bash
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:        16.04
Codename:       xenial
# qemu-img --version
qemu-img version 3.0.1
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers

The latest LTS version for Ubuntu is 20.04, which has newer versions of important dependencies, such as Qemu.

$ docker run -it ubuntu:20.04 /bin/bash
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.2 LTS
Release:        20.04
Codename:       focal
# qemu-img --version
qemu-img version 4.2.1 (Debian 1:4.2-3ubuntu6.16)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

Issue

This actually matters, as numerous bugs, such as for float-point emulation, have been fixed in newer Qemu versions:

In addition, here's a sample code snippet that fails on Qemu 3.0.1 but works on Qemu 4.2.1:

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

double dn1() {
    double num = 1303.0;
    double den = 1e-20;
    return num * den;
}

double dn2() {
    double num = 1303.0;
    double den = 1e20;
    return num / den;
}


float fn1() {
    float num = 1303.0;
    float den = 1e-20;
    return num * den;
}

float fn2() {
    float num = 1303.0;
    float den = 1e20;
    return num / den;
}

int main() {
  float f = fn1();
  uint32_t bf;
  memcpy(&bf, &f, 8);
  printf("%u\n", bf);

  f = fn2();
  memcpy(&bf, &f, 8);
  printf("%u\n", bf);

  double d = dn1();
  uint64_t bd;
  memcpy(&bd, &d, 8);
  printf("%" PRIu64 "\n", bd);

  d = dn2();
  memcpy(&bd, &d, 8);
  printf("%" PRIu64 "\n", bd);

  return 0;
}

If we run the above using Qemu 3.0.1, we get:

# qemu-ppc --version
qemu-ppc version 3.0.1
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers
# qemu-ppc ./main-ppc
594566255
594566255
4354430593920867240
4354430593920867241

If we run the above using Qemu 4.2.1, we get:

# qemu-ppc --version
qemu-ppc version 4.2.1 (qemu-4.2.1-1.fc32)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
# qemu-ppc ./main-ppc
594566255
594566255
4354430593920867240
4354430593920867240

In short, we have a rounding error of 1 ULP due to cross using outdated Ubuntu (and therefore Qemu) versions. Ideally, we'd use version 6.0.1 or v5.0.0 (the latter requiring the following PPA, the former requiring compiling from source).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions