]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Target/SectionLoadList.cpp
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / source / Target / SectionLoadList.cpp
1 //===-- SectionLoadList.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Target/SectionLoadList.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/Section.h"
19 #include "lldb/Core/Stream.h"
20 #include "lldb/Symbol/Block.h"
21 #include "lldb/Symbol/Symbol.h"
22 #include "lldb/Symbol/SymbolContext.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 SectionLoadList::SectionLoadList(const SectionLoadList &rhs) : m_addr_to_sect(), m_sect_to_addr(), m_mutex()
28 {
29     std::lock_guard<std::recursive_mutex> guard(rhs.m_mutex);
30     m_addr_to_sect = rhs.m_addr_to_sect;
31     m_sect_to_addr = rhs.m_sect_to_addr;
32 }
33
34 void
35 SectionLoadList::operator=(const SectionLoadList &rhs)
36 {
37     std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex);
38     std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex);
39     m_addr_to_sect = rhs.m_addr_to_sect;
40     m_sect_to_addr = rhs.m_sect_to_addr;
41 }
42
43 bool
44 SectionLoadList::IsEmpty() const
45 {
46     std::lock_guard<std::recursive_mutex> guard(m_mutex);
47     return m_addr_to_sect.empty();
48 }
49
50 void
51 SectionLoadList::Clear ()
52 {
53     std::lock_guard<std::recursive_mutex> guard(m_mutex);
54     m_addr_to_sect.clear();
55     m_sect_to_addr.clear();
56 }
57
58 addr_t
59 SectionLoadList::GetSectionLoadAddress (const lldb::SectionSP &section) const
60 {
61     // TODO: add support for the same section having multiple load addresses
62     addr_t section_load_addr = LLDB_INVALID_ADDRESS;
63     if (section)
64     {
65         std::lock_guard<std::recursive_mutex> guard(m_mutex);
66         sect_to_addr_collection::const_iterator pos = m_sect_to_addr.find (section.get());
67         
68         if (pos != m_sect_to_addr.end())
69             section_load_addr = pos->second;
70     }
71     return section_load_addr;
72 }
73
74 bool
75 SectionLoadList::SetSectionLoadAddress (const lldb::SectionSP &section, addr_t load_addr, bool warn_multiple)
76 {
77     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
78
79     ModuleSP module_sp (section->GetModule());
80
81     if (module_sp)
82     {
83         if (log)
84         {
85             const FileSpec &module_file_spec (module_sp->GetFileSpec());
86             log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ") module = %p",
87                          __FUNCTION__, static_cast<void*>(section.get()),
88                          module_file_spec.GetPath().c_str(),
89                          section->GetName().AsCString(), load_addr,
90                          static_cast<void*>(module_sp.get()));
91         }
92
93         if (section->GetByteSize() == 0)
94             return false; // No change
95
96         // Fill in the section -> load_addr map
97         std::lock_guard<std::recursive_mutex> guard(m_mutex);
98         sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section.get());
99         if (sta_pos != m_sect_to_addr.end())
100         {
101             if (load_addr == sta_pos->second)
102                 return false; // No change...
103             else
104                 sta_pos->second = load_addr;
105         }
106         else
107             m_sect_to_addr[section.get()] = load_addr;
108
109         // Fill in the load_addr -> section map
110         addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
111         if (ats_pos != m_addr_to_sect.end())
112         {
113             // Some sections are ok to overlap, and for others we should warn. When
114             // we have multiple load addresses that correspond to a section, we will
115             // always attribute the section to the be last section that claims it
116             // exists at that address. Sometimes it is ok for more that one section
117             // to be loaded at a specific load address, and other times it isn't.
118             // The "warn_multiple" parameter tells us if we should warn in this case
119             // or not. The DynamicLoader plug-in subclasses should know which
120             // sections should warn and which shouldn't (darwin shared cache modules
121             // all shared the same "__LINKEDIT" sections, so the dynamic loader can
122             // pass false for "warn_multiple").
123             if (warn_multiple && section != ats_pos->second)
124             {
125                 ModuleSP module_sp (section->GetModule());
126                 if (module_sp)
127                 {
128                     ModuleSP curr_module_sp (ats_pos->second->GetModule());
129                     if (curr_module_sp)
130                     {
131                         module_sp->ReportWarning ("address 0x%16.16" PRIx64 " maps to more than one section: %s.%s and %s.%s",
132                                                   load_addr, 
133                                                   module_sp->GetFileSpec().GetFilename().GetCString(), 
134                                                   section->GetName().GetCString(),
135                                                   curr_module_sp->GetFileSpec().GetFilename().GetCString(),
136                                                   ats_pos->second->GetName().GetCString());
137                     }
138                 }
139             }
140             ats_pos->second = section;
141         }
142         else
143             m_addr_to_sect[load_addr] = section;
144         return true;    // Changed
145
146     }
147     else
148     {
149         if (log)
150         {
151             log->Printf ("SectionLoadList::%s (section = %p (%s), load_addr = 0x%16.16" PRIx64 ") error: module has been deleted",
152                          __FUNCTION__, static_cast<void*>(section.get()),
153                          section->GetName().AsCString(),
154                          load_addr);
155         }
156     }
157     return false;
158 }
159
160 size_t
161 SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp)
162 {
163     size_t unload_count = 0;
164
165     if (section_sp)
166     {
167         Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
168
169         if (log)
170         {
171             ModuleSP module_sp = section_sp->GetModule();
172             std::string module_name("<Unknown>");
173             if (module_sp)
174             {
175                 const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
176                 module_name = module_file_spec.GetPath();
177             }
178             log->Printf ("SectionLoadList::%s (section = %p (%s.%s))",
179                          __FUNCTION__, static_cast<void*>(section_sp.get()),
180                          module_name.c_str(),
181                          section_sp->GetName().AsCString());
182         }
183
184         std::lock_guard<std::recursive_mutex> guard(m_mutex);
185
186         sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
187         if (sta_pos != m_sect_to_addr.end())
188         {
189             ++unload_count;
190             addr_t load_addr = sta_pos->second;
191             m_sect_to_addr.erase (sta_pos);
192
193             addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
194             if (ats_pos != m_addr_to_sect.end())
195                 m_addr_to_sect.erase (ats_pos);
196         }
197     }
198     return unload_count;
199 }
200
201 bool
202 SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp, addr_t load_addr)
203 {
204     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
205
206     if (log)
207     {
208         ModuleSP module_sp = section_sp->GetModule();
209         std::string module_name("<Unknown>");
210         if (module_sp)
211         {
212             const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
213             module_name = module_file_spec.GetPath();
214         }
215         log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ")",
216                      __FUNCTION__, static_cast<void*>(section_sp.get()),
217                      module_name.c_str(),
218                      section_sp->GetName().AsCString(), load_addr);
219     }
220     bool erased = false;
221     std::lock_guard<std::recursive_mutex> guard(m_mutex);
222     sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
223     if (sta_pos != m_sect_to_addr.end())
224     {
225         erased = true;
226         m_sect_to_addr.erase (sta_pos);
227     }
228
229     addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
230     if (ats_pos != m_addr_to_sect.end())
231     {
232         erased = true;
233         m_addr_to_sect.erase (ats_pos);
234     }
235
236     return erased;
237 }
238
239
240 bool
241 SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const
242 {
243     // First find the top level section that this load address exists in
244     std::lock_guard<std::recursive_mutex> guard(m_mutex);
245     if (!m_addr_to_sect.empty())
246     {
247         addr_to_sect_collection::const_iterator pos = m_addr_to_sect.lower_bound (load_addr);
248         if (pos != m_addr_to_sect.end())
249         {
250             if (load_addr != pos->first && pos != m_addr_to_sect.begin())
251                 --pos;
252             const addr_t pos_load_addr = pos->first;
253             if (load_addr >= pos_load_addr)
254             {
255                 addr_t offset = load_addr - pos_load_addr;
256                 if (offset < pos->second->GetByteSize())
257                 {
258                     // We have found the top level section, now we need to find the
259                     // deepest child section.
260                     return pos->second->ResolveContainedAddress (offset, so_addr);
261                 }
262             }
263         }
264         else
265         {
266             // There are no entries that have an address that is >= load_addr,
267             // so we need to check the last entry on our collection.
268             addr_to_sect_collection::const_reverse_iterator rpos = m_addr_to_sect.rbegin();
269             if (load_addr >= rpos->first)
270             {
271                 addr_t offset = load_addr - rpos->first;
272                 if (offset < rpos->second->GetByteSize())
273                 {
274                     // We have found the top level section, now we need to find the
275                     // deepest child section.
276                     return rpos->second->ResolveContainedAddress (offset, so_addr);
277                 }
278             }
279         }
280     }
281     so_addr.Clear();
282     return false;
283 }
284
285 void
286 SectionLoadList::Dump (Stream &s, Target *target)
287 {
288     std::lock_guard<std::recursive_mutex> guard(m_mutex);
289     addr_to_sect_collection::const_iterator pos, end;
290     for (pos = m_addr_to_sect.begin(), end = m_addr_to_sect.end(); pos != end; ++pos)
291     {
292         s.Printf("addr = 0x%16.16" PRIx64 ", section = %p: ",
293                  pos->first, static_cast<void*>(pos->second.get()));
294         pos->second->Dump (&s, target, 0);
295     }
296 }
297
298