Skip to content

Rust binary (after objcopy) too large #6

Open
@crepererum

Description

@crepererum

Abstract

The binary that is flashed via the rust example is over 250MB large, too large for the target system. The C example does NOT suffer from this issue.

Reproduction

  1. Get Rust version 1.45.0
  2. cd r-riscv-blink
  3. cargo build --release (although the issue also exists w/o the release flag)

Technical Details

$ cd target/riscv32i-unknown-none-elf/release/
$ ls -lh r-riscv-blink{,.bin}
-rwxr-xr-x 2 foo bar 456K Jul 25 16:08 r-riscv-blink
-rwxr-xr-x 1 foo bar 257M Jul 25 16:08 r-riscv-blink.bin

So while the input ELF (r-riscv-blink) has a somewhat expected size for an unstripped Rust program, the output binary (r-riscv-blink.bin) is just huge. If we look at the ELF file:

$ readelf -S r-riscv-blink
There are 23 section headers, starting at offset 0x71c18:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text.dummy       PROGBITS        20000000 0000d4 040000 00   A  0   0  1
  [ 2] .text             PROGBITS        20040000 041000 000a14 00  AX  0   0  4
  [ 3] .rodata           PROGBITS        20040a14 041a14 000054 00   A  0   0  4
  [ 4] .data             PROGBITS        10000000 042000 000000 00   A  0   0  4
  [ 5] .bss              NOBITS          10000000 042000 000004 00  WA  0   0  1
  [ 6] .heap             PROGBITS        10000004 042000 000000 00  WA  0   0  1
  [ 7] .stack            PROGBITS        10000004 042000 01fffc 00  WA  0   0  1
  [ 8] .debug_line       PROGBITS        00000000 061ffc 0017e2 00      0   0  1
  [ 9] .debug_info       PROGBITS        00000000 0637de 00380b 00      0   0  1
  [10] .debug_abbrev     PROGBITS        00000000 066fe9 00051e 00      0   0  1
  [11] .debug_aranges    PROGBITS        00000000 067508 000030 00      0   0  8
  [12] .debug_str        PROGBITS        00000000 067538 003c21 01  MS  0   0  1
  [13] .debug_ranges     PROGBITS        00000000 06b160 0005f0 00      0   0  8
  [14] .riscv.attributes RISCV_ATTRIBUTE 00000000 06b750 00001a 00      0   0  1
  [15] .debug_loc        PROGBITS        00000000 06b76a 001362 00      0   0  1
  [16] .debug_pubnames   PROGBITS        00000000 06cacc 001267 00      0   0  1
  [17] .debug_pubtypes   PROGBITS        00000000 06dd33 0011c9 00      0   0  1
  [18] .debug_frame      PROGBITS        00000000 06eefc 000220 00      0   0  4
  [19] .comment          PROGBITS        00000000 06f11c 000013 01  MS  0   0  1
  [20] .symtab           SYMTAB          00000000 06f130 0023a0 10     22 527  4
  [21] .shstrtab         STRTAB          00000000 0714d0 0000ee 00      0   0  1
  [22] .strtab           STRTAB          00000000 0715be 00065a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

Nothing too large here (largest is .text.dummy with 256kB). However, what is bizzare is the following:

$ riscv64-unknown-elf-objcopy -O binary -R .stack r-riscv-blink r-riscv-blink.bin
$ ls -lh r-riscv-blink{,.bin}
-rwxr-xr-x 2 tom tom 456K Jul 25 16:08 r-riscv-blink*
-rwxr-xr-x 1 tom tom 259K Jul 25 16:22 r-riscv-blink.bin*

This looks much better. Is the stack section somewhat broken? Version info:

$ riscv64-unknown-elf-objcopy --version
GNU objcopy (GNU Binutils) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions