0
votes

I just started to learn ADA and how gnat works and there are few things which I don't understand when it comes to elaboration code.

I have been seeing couple of examples where one writes something like this: E003 : Short_Integer; pragma Import (Ada, E003, "XXX_E"), where "XXX" is usually the name of a package.

I was searching in the code for the XXX_E symbol but couldn't find it. Therefor I assume that is somehow generated by gnat?! (or I am wrong?) where can I read more about this?

Thanks,

1
Yeah this is a Gnat-ism. It writes essentially an Ada source file as a wrapper for the actual source code, to bind it to its dependencies. Normally you never need to see this; gnatmake or gprbuild hides it. Look at the docs for "gnatbind". - user_1818839
Could you please point me to some example or specific text in the manual. I don't even know what and how to google it. - user3523954
"Gnatbind documentation", about the 4th hit. gcc.gnu.org/onlinedocs/gcc-4.9.2/gnat_ugn/… See point 3 on this page. - user_1818839
This is part of how GNAT converts Ada (a woman's name, not an acronym) into an executable. It should only be of interest to you if you're working on the GNAT compiler, certainly not something someone learning Ada should be looking at. - Jeffrey R. Carter

1 Answers

5
votes

I don’t believe you’ll find any documents describing why GNAT introduces these <pkg>_E symbols; I guess the developers think you don’t really need to know, and indeed in 20 years of using GNAT I don’t remember ever feeling the need to explore this. You could look at the source (package Sem_Elab looks to have the details).

As for why they’re there, it looks as though it’s to do with checking that a package has been elaborated; looking at a binder-generated package body (b__<main>.adb, or sometimes b~<main>.adb) there’s code like

...
E056 : Short_Integer; pragma Import (Ada, E056, "ada__text_io_E");
...
   Ada.Text_Io'Elab_Spec;
   Ada.Text_Io'Elab_Body;
   E056 := E056 + 1;
...

(E056 is a local name for the two-byte object at address ada__text_io_E) which means "first, elaborate Ada.Text_IO’s spec, then its body, then set a flag to show it’s been fully elaborated".

I’ve not been able to find an example of where this flag has actually been checked, though you can see why it might be needed in this:

package Elaboration is
   function F return Integer;
end Elaboration;

package body Elaboration is
   Value : Integer;
   function F return Integer is (Value);
begin
   Value := 42;
end Elaboration;

If Elaboration.F were to be called before the package body had been elaborated, the contents of Value would be undefined.

By default, GNAT goes to considerable lengths to ensure that access-before-elaboration (ABE) doesn’t occur (maybe this explains why there’s actually no generated check in elaboration.o!)