gnatelim 解決編

動いた…。
gnatelim-process_bind_file.adbのGet_Lineの下に以下を挿入します。

         while Elab_Proc_NInd <= Elab_Proc_NLen loop
           case Elab_Proc_Name (Elab_Proc_NLen) is
           when Character'Val(13) | Character'Val(10) => 
             Elab_Proc_NLen := Elab_Proc_NLen - 1;
           when others => 
             exit;
           end case;
         end loop;

恐らくバイナリファイルを扱うためにbinmodeを使うのでしょう。その上で普通にテキストファイル処理を行ってしまっているため、改行コードまでGet_Lineが取り込んでいるものと思われます。
この時点でCバインダー(gnatbind -C testで生成)は動きます。
Adaバインダーを動かすにはさらに、バージョン違いかなにかで"-- BEGIN ELABORATION ORDER"とかの"--"の後のスペースの数が違いますので地道に修正。

         Result := Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) =
                   "-- END ELABORATION ORDER";

         Result := Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- END ELABORATION ORDER" or else
                   Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "--  END ELABORATION ORDER";
            exit when
               Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen)
               = "-- BEGIN ELABORATION ORDER";

            exit when
               Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- BEGIN ELABORATION ORDER" or else
               Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "--  BEGIN ELABORATION ORDER";

同様にこんな定数決め打ちも…。

         Elab_Proc_NInd := Elab_Proc_NInd + 3;
         --  Skip "-- "

         while Elab_Proc_Name(Elab_Proc_NInd) = '-' loop
           Elab_Proc_NInd := Elab_Proc_NInd + 1;
         end loop;
         while Elab_Proc_Name(Elab_Proc_NInd) = ' ' loop
           Elab_Proc_NInd := Elab_Proc_NInd + 1;
         end loop;

朝から疲れた。

gnatmake -f -c -gnatc -gnatt test
gnatbind test 
gnatelim test > gnat.adc
gnatmake -f test

test.adbに、決して他から呼ばれることがないルーチン(関数内関数でも可)を紛れ込ませておけば、サイズが変わっていることを確認できます。
ここまでしたのですからパッチ送りつけてやりたいなあ…。
ちなみに使い方はhttp://gcc.gnu.org/onlinedocs/gcc-3.4.3/gnat_ugn_unw/Summary-of-the-gnatelim-Usage-Cycle.html参照。

追記
gcc-4.0.1。あとAda2005の機能には残念ながら未対応。

      function Get_Unit_From_C_Elab_Procedure return Compilation_Unit is
      begin
         --  while Elab_Proc_Name (Elab_Proc_NLen) /= ' ' loop
         while Elab_Proc_Name (Elab_Proc_NLen) /= '%' loop
            Elab_Proc_NLen := Elab_Proc_NLen - 1;
         end loop;
         --  Skip "(spec)" or "(body")

         --  if Elab_Proc_Name (Elab_Proc_NLen + 2) = 's' then
         if Elab_Proc_Name (Elab_Proc_NLen + 1) = 's' then
            Spec := True;
         else
            Spec := False;
         end if;

         Elab_Proc_NLen := Elab_Proc_NLen - 1;
         --  Skip ' ' between the unit name and "(spec|body)"

         Unit_Name_Len := Elab_Proc_NLen - Elab_Proc_NInd + 1;
         Unit_Name (1 .. Unit_Name_Len) :=
            To_Lower (Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen));

         --  here we have a unit name as Unit_Name (1 .. Unit_Name_Len);

         if Spec then

            return Library_Unit_Declaration
              (To_Wide_String (Unit_Name (1 .. Unit_Name_Len)), C);
         else

            return Compilation_Unit_Body
              (To_Wide_String (Unit_Name (1 .. Unit_Name_Len)), C);
         end if;

      end Get_Unit_From_C_Elab_Procedure;