I assume your situation is worse than mine was. the person creating the pain was no longer with the company, and we were holding off a re-write.
The structure had pointers to other structures. The desire was to have a mechanism for an alternate boot config without re-compiling the bootloader every time. No more room for additional if-then-else structures. The structures were such that there were pointers to other structures thus the problem, re-arranging the items in the structure would not fix it, stdint would not fix it. the pointer from one structure to another so that the top level functions only needed to pass one structure (I wont get into that now) were the rub. 32 bit pointers on an ARM11. 64 bit pointers on the host computer needing to make an alternate structure. no more room for program space, got rid of one if-then-else we didnt use freeing up just enough bytes to add new-if-then-else code. can map the flash into address space so if the alternate was built such that the code could "simply" point at it then done. normal point at compiled in else point at alternate. So the crossing compile domains was to try to make an x86, 64 bit, host based tool. Fill in the desired structure, but the tool is to make the flash binary (think file) for the bootloader. On the x86 64 bit domain you get 64 bit pointers in the structure, arm 32 bit domain 32 bit, multiple layers of pointers to structs within the structs. My temp solution was not to compile the alternate struct using the x86 tools, compile and link with the 32 bit tools extract (or just build the whole binary) the relevant bytes and put them in flash, with the appropriate amount of size of struct, length, checksum, etc that you would do even if using the same tools on a different day against the same target or similar targets.
I suspect your issue is worse you are crossing perhaps 32 bit to 64 or vice versa and stdint tricks or other wont fix it? They are not there to fix such things btw. can have a struct with
and the compiler is perfectly free to allocate 4x64 bits and align each of those in a natural way within each 64 bit field, or even a 64 bit compiler can choose to say align those on 32 bit boundaries. so long as you stay within the compiler domain the language works you can pass structures around between functions, even ones in different source files, and it will work. Its when you cross to another compiler or version of compiler or same compiler (family) different target, where the implementation defined hits you. So I suspect you landed in one of these traps.
The ideal solution is to have a conversion tool in the original compile domain such that you can read the data into a struct then have an outgoing struct that is different, same element names perhaps but more portable
from which you could leave it like that in the final domain, or that domain could read it in with a higher chance of success into a portable struct then copy the items over into the desired struct to take advantage of clipping or memory savings or whatever.
if you cant do that then maybe the target domain needs padding added to the struct and maybe ifdefs in the shared source if any so that one domain adds padding for a short term hack to be able to read in the code without a complete re-write.
if packing worked then the quick fix would have been to disable alignment checking.