-2

How do I map a memory address to a variable to create a structure at that memory location? I tried the following piece of code to create a struct at the given memory address but it simply dumps the segmentation fault?

The memory location in the code is an Input Region where I need to set certain data and ring the doorbell with an opcode so that the CPU picks up the Input data and does what opcode says it do with the data in input region

    some_struct* some_struct_obj= (some_struct*)0xc321000000;
    memset(some_struct_obj, 0x00, sizeof(some_struct));
CMouse
  • 130
  • 3
  • 19
  • 2
    You can't write to a random address. – Thomas Sablik Aug 17 '20 at 15:17
  • Can I map it to a variable in my C++ code? – CMouse Aug 17 '20 at 15:18
  • 2
    No, you can't. Therefore I asked where the address comes from. If it's a special hardware address you could use it. But you can't write to a random address. How do you know this address is part of your application? – Thomas Sablik Aug 17 '20 at 15:19
  • Well, I am following this https://stackoverflow.com/questions/1554774/create-new-c-object-at-specific-memory-address but couldn't go anywhere. So it is possible the way I see it – CMouse Aug 17 '20 at 15:30
  • What sort of platform are you on? What sot of special hardware does this address point to? Unless this is some sort of special-purpose embedded system, the OS generally has to map addresses in your process's virtual address space to physical addresses. If you try to access a virtual address that isn't mapped to a physical address then that access will fail. – Miles Budnek Aug 17 '20 at 15:32
  • Of course it's possible to reuse allocated memory but you can't use random memory – Thomas Sablik Aug 17 '20 at 15:32
  • If you are following that question, there is an actual answer there - you use placement new assuming address you given is somehow correct. What else are you missing? – Slava Aug 17 '20 at 15:35
  • _"but it simply dumps the segmentation fault"_ That sound like you are not allowed to use this memory address. I asked where this address comes from. Is this a random address or a special hardware address? – Thomas Sablik Aug 17 '20 at 15:38
  • It is an address formed by putting together 2 32 bit address which were output of setpci command. To be more specific it is the BAR0 for a PCIe switch – CMouse Aug 17 '20 at 15:42
  • 2
    On embedded software, you can declare specific variables so that they point to special device-mapped addresses. You will need to read your hardware's development manual, or use it via a library. You should expand your question with more information about your platform and the controller that you use to ring the doorbell. – Jorge Bellon Aug 17 '20 at 15:42
  • "Input Region where I need to set certain data" are you sure it is valid to fill that region with 0 by `memset()` ? – Slava Aug 17 '20 at 15:50
  • I am definitely sure – CMouse Aug 17 '20 at 15:52
  • 1
    If you get segmentation fault on that call, then you are wrong. If coredump happens somewhere else, you need to show that code and ask about it. – Slava Aug 17 '20 at 15:54
  • Actually you're right, it's actually a seg fault at memset ! – CMouse Aug 17 '20 at 16:02
  • You can assign pointers to variables. The pointers can have any value. The pointer must have a valid address when dereferenced, otherwise Undefined Behavior occurs. Remember that compilers are allowed to insert padding between structure members; so structs may not be good for mapping hardware addresses (or registers). Some compilers may allow you to map variables to memory segments, but this is a compiler specific thing and not standard across all platforms. – Thomas Matthews Aug 17 '20 at 16:03

1 Answers1

1

Map a memory address to a variable

There is no way in C++ to choose the exact location of any variable. You can only choose storage class: automatic, static or thread local. The language implementation chooses the address.

How do I map a memory address to ... to create a structure at that memory location?

It is possible to create an object with dynamic storage (which is not a variable) into any memory address as long as that memory is allocated, and doesn't contain non-trivial objects. It can be achieved using placement new expression, or some standard functions that perform placement new internally.

There is no way in standard C++ to allocate memory from arbitrary address. The language implementation takes care of allocating memory for variables and dynamic objects.

On embedded systems without virtual memory, the language implementation may document specific memory address ranges as allocated. In such case, you can simply use placement new to create objects in that memory. Using such addresses won't be portable to other systems.


How about a non-standard way? Yes, it may exist. For example, POSIX standard specifies mmap function:

pa=mmap(addr, len, prot, flags, fildes, off);

The parameter flags provides other information about the handling of the mapped data. The value of flags is the bitwise-inclusive OR of these options, defined in <sys/mman.h>:

Symbolic Constant  Description
MAP_SHARED         Changes are shared.
MAP_PRIVATE        Changes are private.
MAP_FIXED          Interpret addr exactly.

When MAP_FIXED is set in the flags argument, the implementation is informed that the value of pa shall be addr, exactly.

Consider however following from Linux manpages:

The only safe use for MAP_FIXED is where the address range specified by addr and length was previously reserved using another mapping; otherwise, the use of MAP_FIXED is hazardous because it forcibly removes preexisting mappings, making it easy for a multithreaded process to corrupt its own address space.

eerorika
  • 232,697
  • 12
  • 197
  • 326