@ErichStyger
Hi Erich thank you again. Please see my comments / questions below in bold magenta:
It depends what you are exposing. If you are exposing your device and someone can access the memory, then basically you have access to the code and constant data. How this looks you can see in https://mcuoneclipse.com/2019/05/26/reverse-engineering-of-a-not-so-secure-iot-device/ . Basically the information is on assembly instruction level, but still for reverse engineering good enough. You have to protect against this with securing this device, however don't trust too much as there are ways to get around this too on many devices. - Understood, I will use the Flash Security Features on the chip. This may generate more questions, but I will cross that bridge once I get a working release build of the current code.
So basically if you 'share' your device memory or do not protect it, it is pretty much the same information as present in a 'Intel Hex' (or S19 or binary if you want) file. What this means or if you are unfamiliar with these, see https://mcuoneclipse.com/2012/09/27/s-record-intel-hex-and-binary-files/ . If you let someone else (e.g. in the production line) use these files, then you basically expose things as mentioned above. There are ways to mitigate this with so called 'secure provisioning' or vendors like P&E or SEGGER allowing you to send them encrypted images. Or that you use on-chip encryption (which the KE16 does not have imho).- Understood, I have control of the files during production programming so this is less of a concern for my use case.
As mentioned above, the S19/Hex/Binary only contains the code and constant data. If you expose the ELF/Dwarf (.axf, .elf) file (which I hope you do not) it is a complete different story as includes debug information. - How would one expose the ELF/Dwarf information? More importantly, how do I make sure I do not?
So basically it is about how easy it is to understand the assembly code. See https://mcuoneclipse.com/2012/06/01/debug-vs-release/ for the general concept. In short the debug version creates easier to understand assembly code, so it is easier to reverse engineer that one. Are theses two statements below from your post above conflicting?
Debug and Release in the Embedded World
Embedded Debugging is different: If you debug your application, then the debug information remains on the host, while only the code gets downloaded to the target. The debug information is not loaded into the target memory. This means that advantage of a release version does not exist here
Making Reverse Engineering harder: removing the debug information pretty much means decoding and debugging things on assembly level. That makes reverse engineering harder. But only harder, but does not prevent it. So I see little value in this use case
One aspect between debug and release builds usually is that the debug build includes asserts which can add your source file names to the binary, see https://community.nxp.com/t5/MCUXpresso-General/McuxPresso-Binary-file/td-p/1176194 and https://mcuoneclipse.com/2016/03/09/dealing-with-code-size-in-kinetis-sdk-v2-x-projects/ - so NDEBUG switch is about removing asserts reducing code size and getting rid of troublesome printf statements, not necessarily hiding debug information? Later in this link it seems like the message is go ahead and enable debug in your release version since the info is kept on the host. Sorry if I am missing the subtleties, but which one is it? debug info is in the binary or not?
There can be many reasons for this. One could be that your code has a bug (dangling pointer maybe? variable not initialized? or are you using semihosting/printf which does not work without a debug session?) which due the optimizations can result in different things. But you easily can simply keep the debug information in your 'release' build and then debug it: just remove the option to have the debug information removed. You can create a new build configuration (see https://mcuoneclipse.com/2016/05/19/build-configurations-in-eclipse/) from your release build and just add the debug information. Check your debug level and that -s is not activated. This link was helpful for outlining the process here are some notes:
1) Sure enough I missed some printf statements (I thought I stripped them all out)
2) Debug settings are -O0 and -g3 for optimization and debugging respectively / for Release they are -Os and -g
3) I will change release ti -O0 (size and execution time are not a concern in this use case). Not sure what to do with debug settings
Thank you for again Erich!