Browse Source

Merge #10

10: support linking with lld r=dvc94ch a=danc86

Rust now ships an embedded copy of lld, so if we can link crates with lld it will make the getting started experience way smoother (don't need to find a separate GNU ld).

Co-authored-by: Dan Callaghan <djc@djc.id.au>
bors[bot] 6 years ago
parent
commit
691b5ef48a
2 changed files with 19 additions and 32 deletions
  1. 17 30
      riscv-rt/link.x
  2. 2 2
      riscv-rt/src/lib.rs

+ 17 - 30
riscv-rt/link.x

@@ -7,7 +7,7 @@ SECTIONS
 {
 {
   PROVIDE(_stext = ORIGIN(FLASH));
   PROVIDE(_stext = ORIGIN(FLASH));
 
 
-  .text _stext : ALIGN(4)
+  .text ALIGN(_stext,4) :
   {
   {
     /* Put reset handler first in .text section so it ends up as the entry */
     /* Put reset handler first in .text section so it ends up as the entry */
     /* point of the program. */
     /* point of the program. */
@@ -19,21 +19,20 @@ SECTIONS
     *(.text .text.*);
     *(.text .text.*);
   } > FLASH
   } > FLASH
 
 
-  .rodata : ALIGN(4)
+  .rodata ALIGN(4) :
   {
   {
     *(.rodata .rodata.*);
     *(.rodata .rodata.*);
-    . = ALIGN(4);
   } > FLASH
   } > FLASH
 
 
-  PROVIDE(_sbss = ORIGIN(RAM));
-  .bss _sbss : ALIGN(4)
+  .bss :
   {
   {
+    _sbss = .;
     *(.bss .bss.*);
     *(.bss .bss.*);
     . = ALIGN(4);
     . = ALIGN(4);
     _ebss = .;
     _ebss = .;
   } > RAM
   } > RAM
 
 
-  .data _ebss : ALIGN(4)
+  .data : AT(LOADADDR(.rodata) + SIZEOF(.rodata))
   {
   {
     _sidata = LOADADDR(.data);
     _sidata = LOADADDR(.data);
     _sdata = .;
     _sdata = .;
@@ -42,57 +41,45 @@ SECTIONS
     *(.data .data.*);
     *(.data .data.*);
     . = ALIGN(4);
     . = ALIGN(4);
     _edata = .;
     _edata = .;
-  } > RAM AT > FLASH /* LLD fails on AT > FLASH */
+  } > RAM
 
 
   PROVIDE(_heap_size = 0);
   PROVIDE(_heap_size = 0);
 
 
   /* fictitious region that represents the memory available for the heap */
   /* fictitious region that represents the memory available for the heap */
-  .heap _edata (INFO) : ALIGN(4)
+  .heap (INFO) :
   {
   {
     _sheap = .;
     _sheap = .;
     . += _heap_size;
     . += _heap_size;
     . = ALIGN(4);
     . = ALIGN(4);
     _eheap = .;
     _eheap = .;
-  }
+  } > RAM
 
 
   /* fictitious region that represents the memory available for the stack */
   /* fictitious region that represents the memory available for the stack */
-  .stack _eheap (INFO) : ALIGN(4)
+  .stack (INFO) :
   {
   {
     _estack = .;
     _estack = .;
     . = _stack_start;
     . = _stack_start;
     _sstack = .;
     _sstack = .;
-  }
+  } > RAM
 
 
   /* fake output .got section */
   /* fake output .got section */
   /* Dynamic relocations are unsupported. This section is only used to detect
   /* Dynamic relocations are unsupported. This section is only used to detect
      relocatable code in the input files and raise an error if relocatable code
      relocatable code in the input files and raise an error if relocatable code
      is found */
      is found */
-  .got :
+  .got (INFO) :
   {
   {
-    _sgot = .;
     KEEP(*(.got .got.*));
     KEEP(*(.got .got.*));
-    _egot = .;
-  } > RAM AT > FLASH /* LLD fails on AT > FLASH */
-
+  }
 
 
-  /* Due to an unfortunate combination of legacy concerns,
-     toolchain drawbacks, and insufficient attention to detail,
-     rustc has no choice but to mark .debug_gdb_scripts as allocatable.
-     We really do not want to upload it to our target, so we
-     remove the allocatable bit. Unfortunately, it appears
-     that the only way to do this in a linker script is
-     the extremely obscure "INFO" output section type specifier. */
-  /* a rustc hack will force the program to read the first byte of this section,
-     so we'll set the (fake) start address of this section to something we're
-     sure can be read at runtime: the start of the .text section */
-  /* LLD fails to parse _stext (INFO) */
-  .debug_gdb_scripts _stext (INFO) : {
-    KEEP(*(.debug_gdb_scripts))
+  /* Discard .eh_frame, we are not doing unwind on panic so it is not needed */
+  /DISCARD/ :
+  {
+    *(.eh_frame);
   }
   }
 }
 }
 
 
 /* Do not exceed this mark in the error messages below                | */
 /* Do not exceed this mark in the error messages below                | */
-ASSERT(_sgot == _egot, "
+ASSERT(SIZEOF(.got) == 0, "
 .got section detected in the input files. Dynamic relocations are not
 .got section detected in the input files. Dynamic relocations are not
 supported. If you are linking to C code compiled using the `gcc` crate
 supported. If you are linking to C code compiled using the `gcc` crate
 then modify your build script to compile the C code _without_ the
 then modify your build script to compile the C code _without_ the

+ 2 - 2
riscv-rt/src/lib.rs

@@ -205,7 +205,7 @@ extern "C" {
 /// pointer. Then it calls _start_rust.
 /// pointer. Then it calls _start_rust.
 #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
 #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
 global_asm!(r#"
 global_asm!(r#"
-.section .init
+.section .init, "ax"
 .globl _start
 .globl _start
 _start:
 _start:
   .cfi_startproc
   .cfi_startproc
@@ -295,7 +295,7 @@ macro_rules! entry {
 /// restores caller saved registers and then returns.
 /// restores caller saved registers and then returns.
 #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
 #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
 global_asm!(r#"
 global_asm!(r#"
-  .section .trap
+  .section .trap, "ax"
   .align 4
   .align 4
   .global _start_trap
   .global _start_trap