GCC Rust Weekly Status Report 56

Thanks again to Open Source Security, inc and Embecosm for their ongoing support for this project.

Milestone Progress

Another week into July, we closed out the imports and visibility milestone. This allows us to focus on bug fixing and const generics, and I have also adjusted our expected target dates for the milestones as we went over previously. Moving forward, we hope to focus on not losing too much time as we know that September is a busy month with three back-to-back conferences for us, which will impact development. In other news, we have started extracting patches from gccrs that affect GCC for review on gcc-patches.

Completed Activities

  • cpp const-exprt porting PR1369
  • Support more foreign ABI’s PR1375 PR1379
  • Bug fix bad arithmetic type checking on generics PR1384
  • Support generics in AST dump PR1382
  • Support arithmetic expressions in AST dump PR1381
  • Bug fix support aggregate types in transmute PR1380
  • Add crate helpers in mappings class PR1388
  • External items with Rust ABI need name mangling PR1387
  • Fix undefined behaviour with unique_ptr PR1386
  • Add missing include PR1385
  • Update build farm badges PR1390
  • Extern crate loading PR1362
  • Fix ICE on extern block PR1391

Contributors this week

Overall Task Status

CategoryLast WeekThis WeekDelta
TODO151152+1
In Progress2727
Completed410413+3
GitHub Issues

Test Cases

CategoryLast WeekThis WeekDelta
Passing64426468+26
Failed
XFAIL3131
XPASS
make check-rust

Bugs

CategoryLast WeekThis WeekDelta
TODO6869+1
In Progress1112+1
Completed170172+2
GitHub Bugs

Milestone Progress

MilestoneLast WeekThis WeekDeltaStart DateCompletion DateTarget
Data Structures 1 – Core100%100%30th Nov 202027th Jan 202129th Jan 2021
Control Flow 1 – Core100%100%28th Jan 202110th Feb 202126th Feb 2021
Data Structures 2 – Generics100%100%11th Feb 202114th May 202128th May 2021
Data Structures 3 – Traits100%100%20th May 202117th Sept 202127th Aug 2021
Control Flow 2 – Pattern Matching100%100%20th Sept 20219th Dec 202129th Nov 2021
Macros and cfg expansion100100%1st Dec 202131st Mar 202228th Mar 2022
Imports and Visibility98%100%+2%29th Mar 202213th Jul 202227th May 2022
Const Generics15%30%+15%30th May 202229th Aug 2022
Intrinsics0%0%6th Sept 202230th Sept 2022
GitHub Milestones

Risks

RiskImpact (1-3)Likelihood (0-10)Risk (I * L)Mitigation
Rust Language Changes2714Target specific Rustc version for first go
Going over target dates2714Maintain status reports and issue tracking to stakeholders

Planned Activities

  • Investigate type checking const-generic arguments
  • Work on overflow traps
  • Bug fixing
  • Extract target hooks patches for gcc-review

Detailed changelog

Linking crates

In Rust, the entire crate is the compilation unit; for reference, a compilation unit is often referred to as the translation unit in GCC. This means, unlike other languages, a crate is built up with multiple source files. This is all managed by the mod keywords in your source code, such that mod foo will expand automatically to the relative path of foo.rs and include the source code akin to an include nested within a namespace in C++. This has some exciting benefits, notably no need for header files, but this means more complexity because, when linking code, the caller needs to know the calling conventions and type layout information.

To support linking against crates, many things come together to let it happen, so let us look at this by considering a simple example of calling a function in a library. Let us assume we have a library foo with directory structure:

// libfoo/src/lib.rs
fn bar(a:i32) -> i32 {
  a + 2
}

We can compile this by running:

gccrs -g -O2 -frust-crate=foo -c src/lib.rs -o foo.o

This will generate your expected object file, but you will notice a new output in your current working directory: foo.rox. This is your crate metadata; it contains all this “header” information, such as functions and type layouts. There is code to this by embedding this metadata directly into the object file, which will be preserved into static libraries, and the compiler will support reading from object files and archives but not shared objects, unfortunately. However, by emitting this separate file, it means its output format is agnostic as this method does not seem to be supported for us on macosx.

Back to the example, in order to link against this object and call the function, we must write code to import it:

// test/src/main.rs
extern crate foo;
use foo::bar;

fn main() {
  let a = bar(123);
}

Now to compile and link this.

gccrs -g -O2 -I../libfoo -c src/main.rs -o main.o
gccrs -o test main.o ../libfoo/foo.o

In the compiler, we see the extern crate declaration, which tells the compiler to look for the external crate foo, which in turn triggers the compiler to look for foo.rox, foo.o or libfoo.a in this case, we will find foo.rox. The front-end loads this data, so we know there is a function named bar. Internally the crate of foo just exports:

extern "Rust" {
  fn bar(a:i32) -> i32;
}

This is more complicated for generics and impl blocks, but the idea is the same. The benefit of exporting raw rust code here is that to support public generics, we just get this for free by reusing the same compiler pipeline.

Note you can use the following options to control this metadata output so far:

  • -frust-embed-metadata this toggles to embed the metadata into .rust_export section of the target asm output default off
  • -frust-metadata-output= specifies the path to directly write the metadata to file

Note 1: that when specifying the location to write this metadata file the compiler will enforce a naming convention of crate_name.rox on the basename of the path as the crate name is critical here. Note 2: this link model is heavily inspired as that from gccgo.

Leave a Reply

Your email address will not be published.