Sign in to follow this  

Ensuring a constant adress location

This topic is 3316 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there anyway to make sure that (across builds) and object gets always created at a specific address? (Admittedly, I would need this ability for a hack.) I remember under Windows there's VirtualAlloc() and I think it can be used to make sure that a specific range of addresses get reserved/comitted (which can then be placement new'ed). Any other way? Alex

Share this post


Link to post
Share on other sites
Quote:
Original post by ak-73

Is there anyway to make sure that (across builds) and object gets always created at a specific address? (Admittedly, I would need this ability for a hack.)

I remember under Windows there's VirtualAlloc() and I think it can be used to make sure that a specific range of addresses get reserved/comitted (which can then be placement new'ed). Any other way?

Alex
VirtualAlloc() doesn't guarantee anything, it's a request not a demand. For debugging, it's probably alright, but you need to be aware that you're not guaranteed to get the address you ask for (What if a DLL is loaded at that address for instance?)

Why do you need this? Is there really no other way?

Share this post


Link to post
Share on other sites


I don't *need* this, fortunately. :-)


I have been intellectually contemplating how to implement an object factory differently after taking a glance Alexandrescu's approach in "Modern C++ Design".

I was wondering if it was possible to use virtual method table addresses for type identification *somehow*:

class SomeGameObjectType : public ObjectType
{
public:
virtual ~SomeGameObjectType();
virtual BaseObject* createGameObject();
}

That class should have a size of sizeof(void*).

Then:

class SomeGameObject : public BaseObject
{
...
ObjectType* type;
...
}


Client Code:
ObjectType type = (ObjectType) readDwordFromFile();
BaseObject* obj = type->createGameObject();



Something like that (the DWORD from file would ideally never have to change across versions, etc)... don't nail me on the specifics. :-) It was just a thought that was loosely floating around right now... :-)

Alex

Share this post


Link to post
Share on other sites
Memory allocated (e.g. code, data and bss) inside the Win32 executable itself is non-relocatable, well, normally anyway (Win32s apparently uses an odd base address and requires relocation information for executables to run, but I don't suppose you're targeting Win3.) So if you need a buffer at a fixed address for whatever reason then perhaps you could simply reserve a sufficiently large global array, at least that way there's no risk of the allocation failing short of running out of address space.
Presumably there's some way of creating a unique segment for the buffer and placing it at a specific (not merely fixed) address, either through the right linker incantations or with a separate tool as you would rebase a DLL.

Share this post


Link to post
Share on other sites
Quote:
Original post by implicit
Memory allocated (e.g. code, data and bss) inside the Win32 executable itself is non-relocatable, well, normally anyway


*Assuming* you have a *stable* .exe, no? :-) However I would like to maintain a stable reserved range of addresses throughout the development cycle.

Quote:

(Win32s apparently uses an odd base address and requires relocation information for executables to run, but I don't suppose you're targeting Win3.) So if you need a buffer at a fixed address for whatever reason then perhaps you could simply reserve a sufficiently large global array, at least that way there's no risk of the allocation failing short of running out of address space.


And if I make plenty of changes in the code, adding other globals or replacing/removing them, will the global array stay in any case at the same base address?

Quote:

Presumably there's some way of creating a unique segment for the buffer and placing it at a specific (not merely fixed) address, either through the right linker incantations or with a separate tool as you would rebase a DLL.


Beats me! :-)

Again: I have merely been contemplating this because I thought whether there might be a good alternative to Alexandrescu's approach. Fortunately I don't *need* this.

Thanks for your thoughts,
Alex

Share this post


Link to post
Share on other sites
I have only done a quick search but one possible avenue would be driver development needs, i would imagine they use defined address space alot. Just a thought

Share this post


Link to post
Share on other sites
Quote:
Original post by Guthur
Think this covers the topic unfortuately not really what i was looking for :p


I wouldn't pursue this much further if there isn't an easy and obvious solution. The approach in Modern C++ Design works; I just thought it might be made a bit prettier. :-)

If one gets "hung up" on side issues like these, one loses track of the big picture and never gets anything *finished*.

Thanks for your help though. :-)

Alex

Share this post


Link to post
Share on other sites
True True Alex, indeed i had to make a similar trade off recently give up on one path not because it was likely to be impossible but would take to long to figure out.

I just happened upon that and thought of this thread :) I was searching about assigning memory and char size. Wish i never thought of looking especially, believe it or not, in regards to char size :s

Share this post


Link to post
Share on other sites
Since there is no such thing as a constant address location to begin with (only special implementation-defined cases where casting a pointer to an integer yields the same result on every run) I would be tempted to say that no, there is no way.

For things that don't have an official existence, such as virtual tables, there's even less of a way without heavy reliance on compiler internals.

On the other hand, there is such thing as a constant pointer difference, and it is enforced using arrays in a perfectly standard way. And it's type-safe, too (so that loading an incorrect file doesn't run arbitrary code in an arbitrary location of your program).

// Give each factory a version-independent constant ID
AbstractFactory *factories[] = {
new ConcreteFactory_1,
new ConcreteFactory_2,
new ConcreteFactory_3
};

// Use the factories
int offset = read_int_from_file();
assert (offset >= 0 && offset < size(factories));
factories[offset]->create();

Share this post


Link to post
Share on other sites
Quote:
Original post by Naurava kulkuri
I guess the fundamental problem is about relocation if you really are determined in doing this. There are a few ways to make your life easier, assuming Visual Studio: /FIXED (Fixed Base Address) and /BASE (Base Address).


Note that if you're running on Vista, you'll need to use those flags since it randomises the base address of the EXE, stack and heap.

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
Since there is no such thing as a constant address location to begin with (only special implementation-defined cases where casting a pointer to an integer yields the same result on every run) I would be tempted to say that no, there is no way.

For things that don't have an official existence, such as virtual tables, there's even less of a way without heavy reliance on compiler internals.

On the other hand, there is such thing as a constant pointer difference, and it is enforced using arrays in a perfectly standard way. And it's type-safe, too (so that loading an incorrect file doesn't run arbitrary code in an arbitrary location of your program).

// Give each factory a version-independent constant ID
AbstractFactory *factories[] = {
new ConcreteFactory_1,
new ConcreteFactory_2,
new ConcreteFactory_3
};

// Use the factories
int offset = read_int_from_file();
assert (offset >= 0 && offset < size(factories));
factories[offset]->create();


I have been considering all of this also but if one follows that train of thought further one arrives at the solution provided in Modern C++ Design.

The self-registering concrete products are probably the best way to go then (for non-abstract factories).

I gotta check out the Loki library more in-depth. (It's still all for educational purposes only... :-)

Thanks,
Alex

Share this post


Link to post
Share on other sites

This topic is 3316 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this