diff options
| -rw-r--r-- | .github/workflows/rust.yaml | 9 | ||||
| -rw-r--r-- | src/host/imxrt-boot-header.x | 2 | ||||
| -rw-r--r-- | src/host/imxrt-link.x | 1 | ||||
| -rw-r--r-- | tests/inspect_elf.rs | 83 |
4 files changed, 56 insertions, 39 deletions
diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 0f3616c..6b58a5e 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -53,6 +53,15 @@ jobs: with: command: test args: --tests -- --include-ignored + - name: Install ARM GCC + run: sudo apt-get update && sudo apt-get install -y gcc-arm-none-eabi + - name: Check binaries that are linked with GNU's ld + env: + CARGO_TARGET_THUMBV7EM_NONE_EABIHF_RUSTFLAGS: "-C linker=arm-none-eabi-gcc -C link-arg=-mcpu=cortex-m7 -C link-arg=-mfloat-abi=hard -C link-arg=-mfpu=fpv5-d16 -C link-arg=-nostartfiles" + uses: actions-rs/cargo@v1 + with: + command: test + args: --tests -- --ignored boards: runs-on: ubuntu-latest diff --git a/src/host/imxrt-boot-header.x b/src/host/imxrt-boot-header.x index ed9d789..615fc65 100644 --- a/src/host/imxrt-boot-header.x +++ b/src/host/imxrt-boot-header.x @@ -71,7 +71,7 @@ SECTIONS __dcd_start = .; KEEP(*(.dcd)); /* Device Configuration Data */ __dcd_end = .; - __dcd = ((__dcd_end - __dcd_start) > 0) ? __dcd_start : 0; + __dcd = ((__dcd_end - __dcd_start) > 0) ? __dcd_start : ABSOLUTE(0); *(.Reset); /* Jam the imxrt-rt reset handler into flash. */ *(.__pre_init); /* Also jam the pre-init function, since we need it to run before instructions are placed. */ . = ORIGIN(FLASH) + 0x2000; /* Reserve the remaining 8K as a convenience for a non-XIP boot. */ diff --git a/src/host/imxrt-link.x b/src/host/imxrt-link.x index 71b697e..6c28f99 100644 --- a/src/host/imxrt-link.x +++ b/src/host/imxrt-link.x @@ -15,6 +15,7 @@ ENTRY(Reset); EXTERN(__EXCEPTIONS); /* depends on all the these PROVIDED symbols */ EXTERN(DefaultHandler); +EXTERN(__pre_init); PROVIDE(NonMaskableInt = DefaultHandler); EXTERN(HardFaultTrampoline); diff --git a/tests/inspect_elf.rs b/tests/inspect_elf.rs index fa2c11d..34da382 100644 --- a/tests/inspect_elf.rs +++ b/tests/inspect_elf.rs @@ -134,16 +134,27 @@ impl<'a> ImxrtBinary<'a> { .ok_or_else(|| format!("Could not find {section_name} in program").into()) } - fn section_lma(&self, section: &Section) -> u64 { + fn section_lma(&self, section_name: &str) -> u64 { + let sec = self + .section_header(section_name) + .unwrap_or_else(|| panic!("Section {section_name} not found")); + + let contains_section = |phdr: &&goblin::elf::ProgramHeader| { + // The section resides in this part of the program. + sec.sh_offset >= phdr.p_offset + && (sec.sh_offset - phdr.p_offset) + sec.sh_size <= phdr.p_filesz + // The section's address fits in the program's memory. + && sec.sh_addr >= phdr.p_vaddr + && (sec.sh_addr - phdr.p_vaddr) + sec.sh_size <= phdr.p_memsz + }; + self.elf .program_headers .iter() .filter(|phdr| goblin::elf::program_header::PT_LOAD == phdr.p_type) - .find(|phdr| { - phdr.p_vaddr <= section.address && (phdr.p_vaddr + phdr.p_memsz) > section.address - }) - .map(|phdr| section.address - phdr.p_vaddr + phdr.p_paddr) - .unwrap_or(section.address) // VMA == LMA + .find(contains_section) + .map(|phdr| sec.sh_addr + phdr.p_paddr - phdr.p_vaddr) + .unwrap_or(sec.sh_addr) // VMA == LMA } } @@ -205,7 +216,7 @@ fn imxrt1010evk() { stack, "stack not at ORIGIN(DTCM), or not 8 KiB large" ); - assert_eq!(binary.section_lma(&stack), stack.address); + assert_eq!(binary.section_lma(".stack"), stack.address); let vector_table = binary.section(".vector_table").unwrap(); assert_eq!( @@ -220,12 +231,12 @@ fn imxrt1010evk() { vector_table.address % 1024 == 0, "vector table is not 1024-byte aligned" ); - assert_eq!(binary.section_lma(&vector_table), 0x6000_2000); + assert_eq!(binary.section_lma(".vector_table"), 0x6000_2000); let text = binary.section(".text").unwrap(); assert_eq!(text.address, ITCM, "text"); assert_eq!( - binary.section_lma(&text), + binary.section_lma(".text"), 0x6000_2000 + vector_table.size, "text VMA expected behind vector table" ); @@ -236,7 +247,7 @@ fn imxrt1010evk() { 0x6000_2000 + vector_table.size + aligned(text.size, 16), "rodata LMA & VMA expected behind text" ); - assert_eq!(rodata.address, binary.section_lma(&rodata)); + assert_eq!(rodata.address, binary.section_lma(".rodata")); let data = binary.section(".data").unwrap(); assert_eq!(data.address, 0x2020_0000, "data VMA in OCRAM"); @@ -245,7 +256,7 @@ fn imxrt1010evk() { "blink-rtic expected to have a single static mut u32" ); assert_eq!( - binary.section_lma(&data), + binary.section_lma(".data"), rodata.address + aligned(rodata.size, 4), "data LMA starts behind rodata" ); @@ -256,7 +267,7 @@ fn imxrt1010evk() { data.address + aligned(data.size, 4), "bss in OCRAM behind data" ); - assert_eq!(binary.section_lma(&bss), bss.address, "bss is NOLOAD"); + assert_eq!(binary.section_lma(".bss"), bss.address, "bss is NOLOAD"); let uninit = binary.section(".uninit").unwrap(); assert_eq!( @@ -265,7 +276,7 @@ fn imxrt1010evk() { "uninit in OCRAM behind bss" ); assert_eq!( - binary.section_lma(&uninit), + binary.section_lma(".uninit"), uninit.address, "uninit is NOLOAD" ); @@ -280,7 +291,7 @@ fn imxrt1010evk() { "1 KiB heap in DTCM behind vector table" ); assert_eq!(heap.size, 1024); - assert_eq!(binary.section_lma(&heap), heap.address, "Heap is NOLOAD"); + assert_eq!(binary.section_lma(".heap"), heap.address, "Heap is NOLOAD"); } fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { @@ -314,7 +325,7 @@ fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { stack, "stack not at ORIGIN(DTCM), or not 8 KiB large" ); - assert_eq!(binary.section_lma(&stack), stack.address); + assert_eq!(binary.section_lma(".stack"), stack.address); let vector_table = binary.section(".vector_table").unwrap(); assert_eq!( @@ -329,16 +340,16 @@ fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { vector_table.address % 1024 == 0, "vector table is not 1024-byte aligned" ); - assert_eq!(binary.section_lma(&vector_table), 0x6000_2000); + assert_eq!(binary.section_lma(".vector_table"), 0x6000_2000); let text = binary.section(".text").unwrap(); assert_eq!( text.address, - binary.section_lma(&vector_table) + vector_table.size, + binary.section_lma(".vector_table") + vector_table.size, "text" ); assert_eq!( - binary.section_lma(&text), + binary.section_lma(".text"), 0x6000_2000 + vector_table.size, "text VMA expected behind vector table" ); @@ -349,10 +360,7 @@ fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { vector_table.address + vector_table.size, "rodata LMA & VMA expected behind text" ); - assert_eq!( - binary.section_lma(&rodata), - binary.section_lma(&text) + aligned(text.size, 16) - ); + assert!(binary.section_lma(".rodata") >= binary.section_lma(".text") + aligned(text.size, 4)); let data = binary.section(".data").unwrap(); assert_eq!( @@ -365,8 +373,8 @@ fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { "blink-rtic expected to have a single static mut u32" ); assert_eq!( - binary.section_lma(&data), - binary.section_lma(&rodata) + aligned(rodata.size, 4), + binary.section_lma(".data"), + binary.section_lma(".rodata") + aligned(rodata.size, 4), "data LMA starts behind rodata" ); @@ -376,7 +384,7 @@ fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { data.address + aligned(data.size, 4), "bss in DTCM behind data" ); - assert_eq!(binary.section_lma(&bss), bss.address, "bss is NOLOAD"); + assert_eq!(binary.section_lma(".bss"), bss.address, "bss is NOLOAD"); let uninit = binary.section(".uninit").unwrap(); assert_eq!( @@ -385,7 +393,7 @@ fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { "uninit in DTCM behind bss" ); assert_eq!( - binary.section_lma(&uninit), + binary.section_lma(".uninit"), uninit.address, "uninit is NOLOAD" ); @@ -399,7 +407,7 @@ fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32) { heap, "1 KiB heap in DTCM behind uninit" ); - assert_eq!(binary.section_lma(&heap), heap.address, "Heap is NOLOAD"); + assert_eq!(binary.section_lma(".heap"), heap.address, "Heap is NOLOAD"); } #[test] @@ -492,7 +500,7 @@ fn imxrt1170evk_cm7() { stack, "stack not at ORIGIN(DTCM), or not 8 KiB large" ); - assert_eq!(binary.section_lma(&stack), stack.address); + assert_eq!(binary.section_lma(".stack"), stack.address); let vector_table = binary.section(".vector_table").unwrap(); assert_eq!( @@ -507,12 +515,12 @@ fn imxrt1170evk_cm7() { vector_table.address % 1024 == 0, "vector table is not 1024-byte aligned" ); - assert_eq!(binary.section_lma(&vector_table), 0x3000_2000); + assert_eq!(binary.section_lma(".vector_table"), 0x3000_2000); let text = binary.section(".text").unwrap(); assert_eq!(text.address, ITCM, "text"); assert_eq!( - binary.section_lma(&text), + binary.section_lma(".text"), 0x3000_2000 + vector_table.size, "text VMA expected behind vector table" ); @@ -523,9 +531,8 @@ fn imxrt1170evk_cm7() { vector_table.address + vector_table.size, "rodata moved to DTCM behind vector table" ); - assert_eq!( - binary.section_lma(&rodata), - 0x3000_2000 + vector_table.size + aligned(text.size, 16), + assert!( + binary.section_lma(".rodata") >= 0x3000_2000 + vector_table.size + aligned(text.size, 4), ); let data = binary.section(".data").unwrap(); @@ -535,8 +542,8 @@ fn imxrt1170evk_cm7() { "blink-rtic expected to have a single static mut u32" ); assert_eq!( - binary.section_lma(&data), - binary.section_lma(&rodata) + aligned(rodata.size, 4), + binary.section_lma(".data"), + binary.section_lma(".rodata") + aligned(rodata.size, 4), "data LMA starts behind rodata" ); @@ -546,7 +553,7 @@ fn imxrt1170evk_cm7() { data.address + aligned(data.size, 4), "bss in OCRAM behind data" ); - assert_eq!(binary.section_lma(&bss), bss.address, "bss is NOLOAD"); + assert_eq!(binary.section_lma(".bss"), bss.address, "bss is NOLOAD"); let uninit = binary.section(".uninit").unwrap(); assert_eq!( @@ -555,7 +562,7 @@ fn imxrt1170evk_cm7() { "uninit in OCRAM behind bss" ); assert_eq!( - binary.section_lma(&uninit), + binary.section_lma(".uninit"), uninit.address, "uninit is NOLOAD" ); @@ -569,5 +576,5 @@ fn imxrt1170evk_cm7() { heap, "0 byte heap in DTCM behind rodata table" ); - assert_eq!(binary.section_lma(&heap), heap.address, "Heap is NOLOAD"); + assert_eq!(binary.section_lma(".heap"), heap.address, "Heap is NOLOAD"); } |
