I wish to retract this version of the patch and request that the first version 
(posted on 22/11/2024) be considered instead.

> On 24 Nov 2024, at 11:23, Simon Wright <si...@pushface.org> wrote:
> 
> If s-trasym.adb (System.Traceback.Symbolic, used as a renaming by
> GNAT.Traceback.Symbolic) is given a traceback from a
> position-independent executable, it does not include the executable's
> load address in the report. This is necessary in order to decode the
> traceback report.
> 
> Note, this has already been done for s-trasym__dwarf.adb, which really
> does produce a symbolic traceback; s-trasym.adb is the version used in
> systems which don't actually support symbolication.
> 
> Bootstrapped and regtested (ada onlyj) on x86_64-apple-darwin.
> 
> * gcc/ada/libgnat/s-trasym.adb: Returns the traceback in the required
>   form. Note that leading zeros are trimmed from hexadecimal strings.
> (Symbolic_Traceback): Import Executable_Load_Address.
> (Load_Address): New, from call to Executable_Load_Address.
> (One_If_Executable_Is_PI): New, 0 if Load_Address is null, 1 if
>   not.
> (Image_Length): New, found by calling System.Address_Image on
>   the first address in the traceback. NB, doesn't include "0x".
> (Load_Address_Prefix): New, String containing the required value.
> (Length_Needed): New, computed using the number of elements
>   in the traceback, plus the load address if the executable is PIE.
> (Result): New String of the required length (which will be an
>   overestimate).
> 
> 2024-11-24  Simon Wright   <si...@pushface.org>
> 
> gcc/ada/Changelog:
> 
> PR target/117538
> * libgnat/s-trasym.adb: Returns the traceback, with the program load
> address if applicable.
> 
> ---
> diff --git a/gcc/ada/libgnat/s-trasym.adb b/gcc/ada/libgnat/s-trasym.adb
> index 894fcf37ffd..5351f6fda9b 100644
> --- a/gcc/ada/libgnat/s-trasym.adb
> +++ b/gcc/ada/libgnat/s-trasym.adb
> @@ -53,19 +53,63 @@ package body System.Traceback.Symbolic is
> 
>       else
>          declare
> -            Img : String := System.Address_Image (Traceback 
> (Traceback'First));
> -
> -            Result : String (1 .. (Img'Length + 3) * Traceback'Length);
> -            Last   : Natural := 0;
> +            function Executable_Load_Address return System.Address;
> +            pragma Import
> +              (C, Executable_Load_Address,
> +               "__gnat_get_executable_load_address");
> +
> +            Load_Address : constant System.Address :=
> +              Executable_Load_Address;
> +            One_If_Executable_Is_PI : constant Natural :=
> +              Boolean'Pos (Load_Address /= Null_Address);
> +
> +            --  How long is an Address_Image? (hex digits only).
> +            Image_Length : constant Natural :=
> +              System.Address_Image (Traceback (Traceback'First))'
> +                Length;
> +
> +            Load_Address_Prefix : constant String :=
> +              "Load address: ";
> +
> +            --  For each address to be output, we need the preceding "%x"
> +            --  and a trailing space, making 3 additional characters.
> +            --  There are 2 additional LFs.
> +            Length_Needed : constant Positive :=
> +              (Load_Address_Prefix'Length *
> +               One_If_Executable_Is_PI) +
> +              (Image_Length + 3) *
> +                (Traceback'Length + One_If_Executable_Is_PI) +
> +              2;
> +
> +            Result : String (1 .. Length_Needed);
> +
> +            Last : Natural := 0;
> 
>          begin
> +
> +            if One_If_Executable_Is_PI /= 0 then
> +               declare
> +                  Item : constant String :=
> +                    Load_Address_Prefix & "0x" &
> +                    System.Address_Image (Load_Address) &
> +                    ASCII.LF;
> +               begin
> +                  Last := Item'Length;
> +                  Result (1 .. Last) := Item;
> +               end;
> +            end if;
> +
>             for J in Traceback'Range loop
> -               Img := System.Address_Image (Traceback (J));
> -               Result (Last + 1 .. Last + 2)          := "0x";
> -               Last                                   := Last + 2;
> -               Result (Last + 1 .. Last + Img'Length) := Img;
> -               Last                                   := Last + Img'Length + 
> 1;
> -               Result (Last)                          := ' ';
> +               declare
> +                  Img : constant String :=
> +                    System.Address_Image (Traceback (J));
> +               begin
> +                  Result (Last + 1 .. Last + 2) := "0x";
> +                  Last := Last + 2;
> +                  Result (Last + 1 .. Last + Img'Length) := Img;
> +                  Last := Last + Img'Length + 1;
> +                  Result (Last) := ' ';
> +               end;
>             end loop;
> 
>             Result (Last) := ASCII.LF;
> 

Reply via email to