knurling-rs / flip-link

Adds zero-cost stack overflow protection to your embedded programs
Apache License 2.0
279 stars 8 forks source link

Problem with memory.x in the project root #22

Closed DerFetzer closed 3 years ago

DerFetzer commented 3 years ago

When the linker script with RAM location is in the root directory where you invoke cargo it is always used by the linker. So only the beginning of the stack is changed which leads to an invalid memory layout.

When you look at the man page for GNU ld it says for the -T option:

If scriptfile does not exist in the current directory, "ld" looks for it in the directories specified by any preceding -L options.

So it seems that this is also valid for included scripts.

As a first attempt to fix this problem I set the working dir for the second linker invocation to the temp dir containing the modified script. This works for my setup where I have a memory.x in the project root as well as for the example app in this repository.

It could be a problem though when you have multiple linker scripts in project root. But maybe you could set the project root as additional -L directory. What do you think?

japaric commented 3 years ago

Thanks for the PR! The solution looks good to me.

It could be a problem though when you have multiple linker scripts in project root. But maybe you could set the project root as additional -L directory. What do you think?

Yeah, I tested this out with your changes and these linker scripts in the root of the project:

$ cat memory.x
MEMORY
{
  FLASH : ORIGIN = 0x08000000, LENGTH = 256K
  RAM : ORIGIN = 0x20000000, LENGTH = 64K
}

INCLUDE empty.x

$ touch empty.x

$ cargo b
(..)
= note: rust-lld: error: memory.x:7: cannot find linker script empty.x

The linker fails to find linker scripts that weren't modified by flip-link so we should include the project root in the search path via a -L flag, I think.

japaric commented 3 years ago

Awesome, thanks again!

DerFetzer commented 3 years ago

You are welcome!