0

I want to dump all global and static variables to a file and load them back on the next program invocation. A solution I thought of is to dump the .data segment to a file. But .data segment on a 32bit machine spans over 2^32 address space (4GB). In which part of this address space the variables reside? How do I know which part of the .data segment I should dump?

And when loading the dumped file, I guess that since the variables are referenced by offset in the data segment, it will be safe to just memcpy the whole dump to the alleged starting point of the "variables area". Please correct me if I am wrong.

EDIT

A good start is this question.

Community
  • 1
  • 1
Z Kim
  • 407
  • 1
  • 3
  • 7

5 Answers5

1

Your problem is how to find the beginning and the end of the data segment. I am not sure how to do this, but I could give you a couple of ideas.

If all your data are relatively self-contained, (they are declared within the same module, not in separate modules,) you might be able to declare them within some kind of structure, so the beginning will be the address of the structure, and the end will be some variable that you will declare right after the structure. If I remember well, MASM had a "RECORD" directive or something like that which you could use to group variables together.

Alternatively, you may be able to declare two additional modules, one with a variable called "beginning" and another with a variable called "end", and make sure that the first gets linked before anything else, and the second gets linked after everything else. This way, these variables might actually end up marking the beginning and the end of the data segment. But I am not sure about this, I am just giving you a pointer.

One thing to remember is that your data will inevitably contain pointers, so saving and loading all your data will only work if the OS under which you are running can guarantee that your program will always be loaded in the same address. If not, forget it. But if you can have this guarantee, then yes, loading the data should work. You should not even need a memcpy, just set the buffer for the read operation to be the beginning of the data segment.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • The note on pointers is a good one! Didn't think of it, and it probably makes the "dumping" idea unfeasible. – Z Kim Jan 03 '12 at 16:37
0

The state of an entire program can be very complicated, and will not only involve variables but values in registers. You'll almost certainly be better off keeping track of what data you want to store and then storing it to a file yourself. This can be relatively painless with the right setup and encapsulation. Then when you resume the application, read in the program state and resume.

Dan Fego
  • 13,644
  • 6
  • 48
  • 59
  • Thank you, but this doesn't answer my question. I am very aware of your suggested solution, and I will go for it if I have no other choise. But I have too many variables to carry for and right now I try to avoid it. – Z Kim Jan 03 '12 at 16:25
0

Assuming you are using gnu tools (gcc, binutils) if you look at the linker scripts the embedded folks use like the gba developers and microcontroller developers using roms (yagarto or devkit-arm for example). In the linker script they surround the segments of interest with variables that they can use elsewhere in their code. For rom based software for example you specify the data segment with a ram AT rom or rom AT ram in the linker script meaning link as if the data segment is in ram at this address space, but also link the data itself into rom at this address space, the boot code then copies the .data segment from the rom to the ram using these variables. I dont see why you couldnt do the same thing to have the compiler/linker tools tell you where stuff is then runtime use those variables to grab the data from memory and save it somewhere to hybernate or shut down and then restore that data from wherever. The variables you use to perform the restore of course should not be part of the .data segment or you trash the variables you are using to restore the segment.

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • same goes for .bss, just make sure the variables/code you use to perform the restore is in neither segment, use local, nonstatic, variables for example. – old_timer Jan 03 '12 at 21:06
0

In response to your header question, on Windows, the location and size of the data and bss segments can be obtained from the in-memory PE header. How that is laid out and how to parse it is documented in this specification:

http://msdn.microsoft.com/en-us/windows/hardware/gg463119

-1

I do not believe that there is a guarantee that with every execution you will have the sam sequence of variables, hence the offsets may point to the wrong content.

Mario The Spoon
  • 4,799
  • 1
  • 24
  • 36
  • How could the sequence of variables change once the program was compiled? The variables are just offsets in memory and offsets are set at compilation. – Z Kim Jan 03 '12 at 16:19
  • 1
    This is only true iff the program is compiled and linked as positionally independent (PIC). Usually, when loading a program, all addresses are `relocated` - to the location the program is loaded to. This is not neccessarily the same on every start – Gunther Piez Jan 03 '12 at 16:23
  • @drhirsch: where can I read about it further? Specifically, about addresses relocation upon program loading. – Z Kim Jan 03 '12 at 16:41
  • @drhirsch The last paragraph of my answer is a bit more to the point with this respect. The variables will always be in the same sequence. Their location will only change. So, there will only be a problem if they contain pointers. – Mike Nakis Jan 03 '12 at 16:42