Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ld: Check for alignment between FLASH_START and linker page size #495

Merged
merged 1 commit into from
Aug 24, 2023

Conversation

bradjc
Copy link
Contributor

@bradjc bradjc commented Aug 7, 2023

This PR is on top of the make updates because that lets me test it. We only care about the latest commit: 79e25cf

The llvm linker seems to make sure the first segment is aligned to a flash page, and assumes the page size is 0x10000. This causes elfs with a segment before what we set as the start of flash:

readelf.py -lS target/cortex-m4.0x00048000.0x1000a000/console
There are 22 section headers, starting at offset 0x26f1c

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .start            PROGBITS        00048080 008080 000074 00  AX  0   0  1
  [ 2] .text             PROGBITS        000480f4 0080f4 0016c8 00  AX  0   0  2
  [ 3] .rodata           PROGBITS        000497bc 0097bc 0001ec 00   A  0   0  4
  [ 4] .stack            NOBITS          1000a000 00a000 000100 00  WA  0   0  1
  [ 5] .data             PROGBITS        1000a100 00a100 000000 00  WA  0   0  1
  [ 6] .bss              NOBITS          1000a100 00a100 000000 00  WA  0   0  1
  [ 7] .debug_loc        PROGBITS        00000000 00a100 0011c5 00      0   0  1
  [ 8] .debug_abbrev     PROGBITS        00000000 00b2c5 0003f3 00      0   0  1
  [ 9] .debug_info       PROGBITS        00000000 00b6b8 007c0d 00      0   0  1
  [10] .debug_aranges    PROGBITS        00000000 0132c5 000108 00      0   0  1
  [11] .debug_ranges     PROGBITS        00000000 0133cd 001278 00      0   0  1
  [12] .debug_str        PROGBITS        00000000 014645 009310 01  MS  0   0  1
  [13] .debug_pubnames   PROGBITS        00000000 01d955 004e3e 00      0   0  1
  [14] .debug_pubtypes   PROGBITS        00000000 022793 001021 00      0   0  1
  [15] .ARM.attributes   ARM_ATTRIBUTES  00000000 0237b4 000032 00      0   0  1
  [16] .debug_frame      PROGBITS        00000000 0237e8 000358 00      0   0  4
  [17] .debug_line       PROGBITS        00000000 023b40 0020c0 00      0   0  1
  [18] .comment          PROGBITS        00000000 025c00 000013 01  MS  0   0  1
  [19] .symtab           SYMTAB          00000000 025c14 0005c0 10     21  76  4
  [20] .shstrtab         STRTAB          00000000 0261d4 0000e1 00      0   0  1
  [21] .strtab           STRTAB          00000000 0262b5 000c65 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Elf file type is EXEC (Executable file)
Entry point is 0x480a1
There are 6 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00040034 0x00040034 0x000c0 0x000c0 R   0x4
  LOAD           0x000000 0x00040000 0x00040000 0x000f4 0x000f4 R   0x10000  // <-- This is before where we said flash starts.
  LOAD           0x008080 0x00048080 0x00048080 0x0173c 0x0173c R E 0x10000
  LOAD           0x0097bc 0x000497bc 0x000497bc 0x001ec 0x001ec R   0x10000
  LOAD           0x00a000 0x1000a000 0x000499a8 0x00100 0x00100 RW  0x10000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x0

 Section to Segment mapping:
  Segment Sections...
   00
   01
   02     .start .text
   03     .rodata
   04     .stack
   05

These elfs are undesirable. This patch allows the linker to check if this case is going to happen.

The fix is adding

println!("cargo:rustc-link-arg=-zmax-page-size=4096");

to build.rs.

@lschuermann
Copy link
Member

lschuermann commented Aug 7, 2023

I'm linking #477 here, as this seems to be a generalization of that issue. I have made too many wrong assumptions about linkers and ELF files to confidently say that this is the correct fix™, but it seems like a strict improvement.

I'm wondering whether we can decrease the page-size even further and thus gain more flexible alignment (maybe down to the word size even)? That might just work, as we use elf2tab as a flash-loader, which is not bound by the typical MMU page-alignment constraints used for dynamic ELF loaders.

A mismatch here causes undesirable ELFs.
@bradjc
Copy link
Contributor Author

bradjc commented Aug 15, 2023

This is coupled with #503.

@bradjc
Copy link
Contributor Author

bradjc commented Aug 24, 2023

I think we can merge this now.

@jrvanwhy jrvanwhy added the upkeep Indicates a PR is upkeep as defined by the code review policy. label Aug 24, 2023
@jrvanwhy jrvanwhy added this pull request to the merge queue Aug 24, 2023
Merged via the queue into master with commit d8bf07a Aug 24, 2023
3 checks passed
@jrvanwhy jrvanwhy deleted the make-all-tab-ldassert branch August 24, 2023 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
upkeep Indicates a PR is upkeep as defined by the code review policy.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants