Intro

Fedora is a Linux Distribution, and GCC is its system compiler

What happens if an upstream package only supports Clang builds?

Confronting Clang and Fedora

Serge « sans paille » Guelton

Compiler Engineer / Wood Craft Lover / RedHat employee

FOSDEM'20 — 1st february 2020

It that started all

Original work started because of this thread:

https://pagure.io/fesco/issue/2020

#2020 Firefox is switching from gcc to clang/llvm Closed: Rejected a year ago

Thread summary (1)

Mozilla upstream switches from gcc to clang and we're going to follow upstream here due to clang performance, maintenance costs and compilation speed.

(later)

the debuginfo generated by it (clang) was pretty broken (...)

clang/llvm doesn't generate asynchronous unwind tables on all architectures (...)

currently testing if -fno-semantics-interposition (the default behavior of clang, but not of gcc) doesn't affect significantly the non-LTO builds

Thread summary (2)

there are security issues (llvm doesn't implement e.g. -D_FORTIFY_SOURCE=2 properly)

As for security, -fstack-protector* is another thing not properly implemented in clang

must continue to compile using gcc in order to produce code less vulnerable to attack

Since then... (1)

D71082: Allow system header to provide their own implementation of some builtin [landed]

__fortify_function void *
__NTH (memcpy (void *__restrict __dest,
               const void *__restrict __src,
               size_t __len))
{
  return __builtin___memcpy_chk (
      __dest, __src, __len, __bos0 (__dest));
}

Since then... (2)

D71566: Improve static checks for sprintf and __builtin___sprintf_chk [landed]

char* some(double d) {
  static char buf[4];
  sprintf(buf, "% .2e", d);
  return buf;
}
some.c:4:3: warning: 'sprintf' will   \
always overflow; destination buffer   \
has size 4, but format string expands \
to at least 9 [-Wfortify-source]

Since then... (3)

D72829: Implement -fsemantic-interposition [landed]

static int foo() { return 0;}

int bar() { return 0;}

int foobar() {
    return foo() + bar();
}

Since then... (4)

D68720: Support -fstack-clash-protection for x86 [under review]

void some(unsigned n, unsigned i) {
    volatile char tmp[8000];
    tmp[i] = 1;
}
some:
    subq    $4096, %rsp
    movq    $0, (%rsp)
    subq    $3784, %rsp
    movl    %esi, %eax
    movb    $1, -128(%rsp,%rax)
    addq    $7880, %rsp
    retq

Is that all?

What about other +/- hidden difference between GCC and Clang?

We should try to prevent such surprises

What about taking a step ahead and recompile world?

Acknowledgment

the following relies a lot on Tom Stellard's work on the subject

Requirements

Fedora has made the move to Python 3

Annobin

A GCC plugin that collects hardening flags and emits reports

Setup

How to change the underlying compiler?

How to detect which compiler has been used?

Results Summary

On Rawhide:

TOTAL: 4303 PASS: 3016 FAIL: 1141 WARN: 0 SKIP: 146

Unsupported Flags [#287]

unknown argument: '-fstack-clash-protection'

unknown argument: '-mvectorize-with-neon-quad'

unknown argument: '-maccumulate-outgoing-args'

unknown argument: '-fvar-tracking'

unknown argument: '-fno-trampolines'

unknown argument: '-fno-enforce-eh-specs'

Hooking failed [#473]

XXXX was not built with clang

-Werror hell [#33]

'printf' macro redefined [-Werror,-Wmacro-redefined]

ignoring return value of function declared with 'warn_unused_result' attribute [-Werror,-Wunused-result]

all paths through this function will call itself [-Werror,-Winfinite-recursion]

-ffinite-math-only [#37]

undefined reference to __.*_finite

Configure errors [#28]

ERROR: Compiler cc can not compile programs

configure: error: C compiler cannot create executables

configure: error: Some functions are not usable.

configure: error: libxml2 not found

Packaging issues [#8]

libclang_rt.asan-x86_64.a: No such file or directory

/usr/bin/ld: cannot find .*libclang_rt.profile-x86_64.a: No such file or directory

/usr/bin/ld: cannot find -lgcc_s

Disagreement on the standard [#89]

error: use of undeclared identifier

error: ordered comparison between pointer and zero

int foo(int* ptr) {
    return ptr > 0;
}

Language extensions [#10]

error: function definition is not allowed here

double
foo (double a, double b)
{
  double square (double z) { return z * z; }
  return square (a) + square (b);
}

OpenMP [#9]

OpenMP: error ... not supported by compiler

cannot find -lomp

Packaging genericity

Conclusion

Great opportunity to improve:

Bonus:

error: no member named '__dprintf_chk'

1
SpaceForward
Right, Down, Page DownNext slide
Left, Up, Page UpPrevious slide
GGo to slide number
POpen presenter console
HToggle this help