1
votes

I am new with the usage of for ***'Address use ***. And I was wondering what are the limitation of this usage. So I created the following procedure:

procedure letshack (A : System.Address) is 
      My_String : String(1..100000);
      for My_String'Address use A;
   begin 
      Put(My_String);
   end;

And this raise a EXCEPTION_ACCESS_VIOLATION while the same code with a String that is 100 length don't raise it. More over if i don't use the integer address, this code works properly.

So what are the limitation of for ***'Address use *** usage. Ps : I am using Ada 95 but any information is welcome.

Edit: I understand a part of the behavior. And this is what I suppose. When you start your program a certain stack is allocated and you can write and read in it. Indeed I Wrote the 5th byte with an integer address

Real Addresses |----------------------------| Virtual Addresses
        0x48000|Stack Origine               |0x00
               |                            |
               |                            |
               |                            |
               |                            |
               |End of Stack                |
  0x48000+range|----------------------------|0x00+range

And you get EXCEPTION_ACCESS_VIOLATION if you are out of stack. It seems strange for a "strong" language if it is right. Because it means you can rewrite your own stack and make bad behave.

2
This may depend on the call - specifically the actual for A - not the procedure itself. Make an minimal reproducible example that demonstrates. Obviously, if the whole string doesn't belong to your process something bad will happen. If you're trying to write a virus there are better languages than Ada :-) - user_1818839
Whenever you do an Address overlay like that, you should also do a pragma Import(Ada, My_String); (or the equivalent aspect), to prevent any default initialization of the overlaying object (My_String in this case) - egilhh
@BrianDrummond Assembly language aside, since the possibilities of address computation, bit size issues, suppression of checks etc. are both available and explicit in standard Ada, writing a documented virus can make profitable use of Ada's features. With SPARKAda, the algorithms of the virus may even be proven and possibly verified. Does not seem so bad if what one really wanted to do was writing a virus in a professional setting. - B98
@BrianDrummond I am not trying to make a virus :)))), I am trying to avoid exception in a critical real time environement. So my question is what does specify the comportement of this usage. And what are the limit. And for the Minimal, Complete, and Verifiable example. I would love to be able to do that but I don't understand the behavior. As told in the post if I give to the procedure an address of an integer it don't works with a String length of 100_000 but with a String of 100 it works (where both length are not integer length). - Brighter side
If you're using Gnat, compile with -fstack-check (and a bunch of other flags I forget to make it properly Ada compliant). Anything more IS going to require an MCVE along the lines you have suggested (pass the address of an integer). But your best route forward would be to identify exactly why you think you need SYSTEM.ADDRESS. You almost certainly don't. - user_1818839

2 Answers

1
votes

Finnaly found the behavior. When you start your program the addresses you use are virtual ones in a page. And the part of the system that handle virtual adress make it for a certain size of memory that is allocated to your process which is constant depending on your system as show the following schema:

Real Addresses |----------------------------| Virtual Addresses
        0x48000|Begin of the virtual address|0x00
               |range                       |
               |                            |
               |                            |
               |End of the virtual address  |
               |range                       |
  0x48000+range|----------------------------|0x00+range

You can do anything without allocating variable in it. For example on my windows this size is 4096 bytes according to the variable si.dwPageSize in <windows.h>. And I tested my String can be 4096 bytes long but not 4097 bytes. I must now test it on my embedded system but seems close to the truth.

0
votes

If you have ensured that you have allocated 100_000 consecutive characters in a readable part of memory starting at A, then it should work.

If A is the address of another Ada entity, it is not supposed to work.