===================================================================
@@ -50,15 +50,20 @@
-- Get --
---------
- function Get (Addr : access System.Address) return String is
+ function Get (Addr : System.Address;
+ Load_Addr : access System.Address)
+ return String
+ is
Res : DWORD;
hModule : aliased HANDLE;
Path : String (1 .. 1_024);
begin
+ Load_Addr.all := System.Null_Address;
+
if GetModuleHandleEx
(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- Addr.all,
+ Addr,
hModule'Access) = Win32.TRUE
then
Res := GetModuleFileName (hModule, Path'Address, Path'Length);
===================================================================
@@ -32,8 +32,6 @@
-- This is the GNU/Linux specific version of this package
with Interfaces.C; use Interfaces.C;
-with System.Address_Operations; use System.Address_Operations;
-
separate (System.Traceback.Symbolic)
package body Module_Name is
@@ -134,7 +132,10 @@
-- Get --
---------
- function Get (Addr : access System.Address) return String is
+ function Get (Addr : System.Address;
+ Load_Addr : access System.Address)
+ return String
+ is
-- Dl_info record for Linux, used to get sym reloc offset
@@ -154,13 +155,15 @@
info : aliased Dl_info;
begin
- if dladdr (Addr.all, info'Access) /= 0 then
+ Load_Addr.all := System.Null_Address;
+ if dladdr (Addr, info'Access) /= 0 then
+
-- If we have a shared library we need to adjust the address to
-- be relative to the base address of the library.
if Is_Shared_Lib (info.dli_fbase) then
- Addr.all := SubA (Addr.all, info.dli_fbase);
+ Load_Addr.all := info.dli_fbase;
end if;
return Value (info.dli_fname);
===================================================================
@@ -132,10 +132,12 @@
procedure Build_Cache_For_All_Modules;
-- Create the cache for all current modules
- function Get (Addr : access System.Address) return String;
- -- Returns the module name for the given address, Addr may be updated
- -- to be set relative to a shared library. This depends on the platform.
- -- Returns an empty string for the main executable.
+ function Get (Addr : System.Address;
+ Load_Addr : access System.Address) return String;
+ -- Returns the module name for the given address Addr, or an empty
+ -- string for the main executable. Load_Addr is set to the shared
+ -- library load address if this information is available, or to
+ -- System.Null_Address otherwise.
function Is_Supported return Boolean;
pragma Inline (Is_Supported);
@@ -499,12 +501,14 @@
-- Otherwise, try a shared library
declare
- Addr : aliased System.Address := Traceback (F);
- M_Name : constant String := Module_Name.Get (Addr'Access);
+ Load_Addr : aliased System.Address;
+ M_Name : constant String :=
+ Module_Name.Get (Addr => Traceback (F),
+ Load_Addr => Load_Addr'Access);
Module : Module_Cache;
Success : Boolean;
begin
- Init_Module (Module, Success, M_Name, System.Null_Address);
+ Init_Module (Module, Success, M_Name, Load_Addr);
if Success then
Multi_Module_Symbolic_Traceback
(Traceback,
===================================================================
@@ -372,7 +372,8 @@
function Is_Inside (C : Dwarf_Context; Addr : Address) return Boolean is
begin
- return Addr >= C.Low and Addr <= C.High;
+ return (Addr >= To_Address (To_Integer (C.Low) + C.Load_Slide)
+ and Addr <= To_Address (To_Integer (C.High) + C.Load_Slide));
end Is_Inside;
---------
@@ -771,15 +772,7 @@
procedure Set_Load_Address (C : in out Dwarf_Context; Addr : Address) is
begin
- if Addr = Null_Address then
- return;
- else
- C.Load_Slide :=
- To_Integer (Addr) - Integer_Address (Get_Load_Address (C.Obj.all));
-
- C.Low := To_Address (To_Integer (C.Low) + C.Load_Slide);
- C.High := To_Address (To_Integer (C.High) + C.Load_Slide);
- end if;
+ C.Load_Slide := To_Integer (Addr);
end Set_Load_Address;
------------------
@@ -1523,9 +1516,11 @@
Res : in out System.Bounded_Strings.Bounded_String)
is
use Ada.Characters.Handling;
- C : Dwarf_Context := Cin;
- Addr : Address;
+ C : Dwarf_Context := Cin;
+ Addr_In_Traceback : Address;
+ Addr_To_Lookup : Address;
+
Dir_Name : Str_Access;
File_Name : Str_Access;
Subprg_Name : String_Ptr_Len;
@@ -1543,10 +1538,14 @@
-- If the buffer is full, no need to do any useless work
exit when Is_Full (Res);
- Addr := PC_For (Traceback (J));
+ Addr_In_Traceback := PC_For (Traceback (J));
+
+ Addr_To_Lookup := To_Address
+ (To_Integer (Addr_In_Traceback) - C.Load_Slide);
+
Symbolic_Address
(C,
- To_Address (To_Integer (Addr) + C.Load_Slide),
+ Addr_To_Lookup,
Dir_Name,
File_Name,
Subprg_Name,
@@ -1608,7 +1607,7 @@
if Suppress_Hex then
Append (Res, "...");
else
- Append_Address (Res, Addr);
+ Append_Address (Res, Addr_In_Traceback);
end if;
if Subprg_Name.Len > 0 then
===================================================================
@@ -73,11 +73,11 @@
function Is_Inside (C : Dwarf_Context; Addr : Address) return Boolean;
pragma Inline (Is_Inside);
- -- Return true iff Addr is within the module
+ -- Return true iff a run-time address Addr is within the module
function Low (C : Dwarf_Context) return Address;
pragma Inline (Low);
- -- Return the lowest address of C
+ -- Return the lowest address of C, from the module object file
procedure Dump (C : in out Dwarf_Context);
-- Dump each row found in the object's .debug_lines section to standard out
@@ -165,7 +165,7 @@
type Dwarf_Context (In_Exception : Boolean := False) is record
Load_Slide : System.Storage_Elements.Integer_Address := 0;
Low, High : Address;
- -- Bounds of the module
+ -- Bounds of the module, per the module object file
Obj : SOR.Object_File_Access;
-- The object file containing dwarf sections