1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- G N A T . T R A C E B A C K . S Y M B O L I C . M O D U L E _ N A M E --
9 -- Copyright (C) 2012-2018, AdaCore --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 -- This is the GNU/Linux specific version of this package
33 with Interfaces
.C
; use Interfaces
.C
;
35 separate (System
.Traceback
.Symbolic
)
37 package body Module_Name
is
39 pragma Linker_Options
("-ldl");
41 function Is_Shared_Lib
(Base
: Address
) return Boolean;
42 -- Returns True if a shared library
46 -- 1. We get information about the module containing the address.
48 -- 2. We check that the full pathname is pointing to a shared library.
50 -- 3. for shared libraries, we return the non relocated address (so
51 -- the absolute address in the shared library).
53 -- 4. we also return the full pathname of the module containing this
60 function Is_Shared_Lib
(Base
: Address
) return Boolean is
61 EI_NIDENT
: constant := 16;
62 type u16
is mod 2 ** 16;
64 -- Just declare the needed header information, we just need to read the
65 -- type encoded in the second field.
67 type Elf32_Ehdr
is record
68 e_ident
: char_array
(1 .. EI_NIDENT
);
72 ET_DYN
: constant := 3; -- A shared lib if e_type = ET_DYN
75 pragma Import
(Ada
, Header
);
76 -- Suppress initialization in Normalized_Scalars mode
77 for Header
'Address use Base
;
80 return Header
.e_type
= ET_DYN
;
86 ---------------------------------
87 -- Build_Cache_For_All_Modules --
88 ---------------------------------
90 procedure Build_Cache_For_All_Modules
is
92 type link_map_acc
is access all link_map
;
93 pragma Convention
(C
, link_map_acc
);
95 type link_map
is record
97 -- Base address of the shared object
100 -- Null-terminated absolute file name
105 l_next
, l_prev
: link_map_acc
;
108 pragma Convention
(C
, link_map
);
110 type r_debug_type
is record
112 r_map
: link_map_acc
;
114 pragma Convention
(C
, r_debug_type
);
116 r_debug
: r_debug_type
;
117 pragma Import
(C
, r_debug
, "_r_debug");
122 while lm
/= null loop
123 if Big_String_Conv
.To_Pointer
(lm
.l_name
) (1) /= ASCII
.NUL
then
124 -- Discard non-file (like the executable itself or the gate).
125 Add_Module_To_Cache
(Value
(lm
.l_name
));
129 end Build_Cache_For_All_Modules
;
135 function Get
(Addr
: System
.Address
;
136 Load_Addr
: access System
.Address
)
140 -- Dl_info record for Linux, used to get sym reloc offset
142 type Dl_info
is record
143 dli_fname
: System
.Address
;
144 dli_fbase
: System
.Address
;
145 dli_sname
: System
.Address
;
146 dli_saddr
: System
.Address
;
150 (addr
: System
.Address
;
151 info
: not null access Dl_info
) return int
;
152 pragma Import
(C
, dladdr
, "dladdr");
153 -- This is a Linux extension and not POSIX
155 info
: aliased Dl_info
;
158 Load_Addr
.all := System
.Null_Address
;
160 if dladdr
(Addr
, info
'Access) /= 0 then
162 -- If we have a shared library we need to adjust the address to
163 -- be relative to the base address of the library.
165 if Is_Shared_Lib
(info
.dli_fbase
) then
166 Load_Addr
.all := info
.dli_fbase
;
169 return Value
(info
.dli_fname
);
171 -- Not found, fallback to executable name
186 function Is_Supported
return Boolean is