blob: 1235a37955004ec7cb36250ce26fda23b41a24ae [file] [log] [blame]
Greg Clayton17f69202010-09-14 23:52:43 +00001//===-- 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
24using namespace lldb;
25using namespace lldb_private;
26
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000027SectionLoadList::SectionLoadList(const SectionLoadList &rhs) : m_addr_to_sect(), m_sect_to_addr(), m_mutex()
Greg Claytond5944cd2013-12-06 01:12:00 +000028{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000029 std::lock_guard<std::recursive_mutex> guard(rhs.m_mutex);
Greg Claytond5944cd2013-12-06 01:12:00 +000030 m_addr_to_sect = rhs.m_addr_to_sect;
31 m_sect_to_addr = rhs.m_sect_to_addr;
32}
33
34void
35SectionLoadList::operator=(const SectionLoadList &rhs)
36{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000037 std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex);
38 std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex);
Greg Claytond5944cd2013-12-06 01:12:00 +000039 m_addr_to_sect = rhs.m_addr_to_sect;
40 m_sect_to_addr = rhs.m_sect_to_addr;
41}
42
Greg Clayton17f69202010-09-14 23:52:43 +000043bool
44SectionLoadList::IsEmpty() const
45{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000046 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton6d093452011-02-05 02:25:06 +000047 return m_addr_to_sect.empty();
Greg Clayton17f69202010-09-14 23:52:43 +000048}
49
50void
51SectionLoadList::Clear ()
52{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000053 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton6d093452011-02-05 02:25:06 +000054 m_addr_to_sect.clear();
55 m_sect_to_addr.clear();
Greg Clayton17f69202010-09-14 23:52:43 +000056}
57
58addr_t
Greg Clayton7820bd12012-07-07 01:24:12 +000059SectionLoadList::GetSectionLoadAddress (const lldb::SectionSP &section) const
Greg Clayton17f69202010-09-14 23:52:43 +000060{
61 // TODO: add support for the same section having multiple load addresses
62 addr_t section_load_addr = LLDB_INVALID_ADDRESS;
Greg Clayton10177aa2010-12-08 05:08:21 +000063 if (section)
64 {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000065 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7820bd12012-07-07 01:24:12 +000066 sect_to_addr_collection::const_iterator pos = m_sect_to_addr.find (section.get());
Greg Clayton6d093452011-02-05 02:25:06 +000067
68 if (pos != m_sect_to_addr.end())
69 section_load_addr = pos->second;
Greg Clayton10177aa2010-12-08 05:08:21 +000070 }
71 return section_load_addr;
Greg Clayton17f69202010-09-14 23:52:43 +000072}
73
74bool
Greg Clayton7820bd12012-07-07 01:24:12 +000075SectionLoadList::SetSectionLoadAddress (const lldb::SectionSP &section, addr_t load_addr, bool warn_multiple)
Greg Clayton17f69202010-09-14 23:52:43 +000076{
Greg Clayton5160ce52013-03-27 23:08:40 +000077 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
Greg Clayton17f69202010-09-14 23:52:43 +000078
Greg Claytonfd814c52013-08-13 01:42:25 +000079 ModuleSP module_sp (section->GetModule());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000080
Greg Claytonfd814c52013-08-13 01:42:25 +000081 if (module_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000082 {
Greg Claytonfd814c52013-08-13 01:42:25 +000083 if (log)
Greg Claytonc859e2d2012-02-13 23:10:39 +000084 {
Greg Claytonfd814c52013-08-13 01:42:25 +000085 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",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000087 __FUNCTION__, static_cast<void*>(section.get()),
Greg Claytonfd814c52013-08-13 01:42:25 +000088 module_file_spec.GetPath().c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000089 section->GetName().AsCString(), load_addr,
90 static_cast<void*>(module_sp.get()));
Greg Claytonfd814c52013-08-13 01:42:25 +000091 }
92
93 if (section->GetByteSize() == 0)
94 return false; // No change
95
96 // Fill in the section -> load_addr map
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000097 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Claytonfd814c52013-08-13 01:42:25 +000098 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
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +0000115 // always attribute the section to the be last section that claims it
Greg Claytonfd814c52013-08-13 01:42:25 +0000116 // 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)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000124 {
Greg Claytonfd814c52013-08-13 01:42:25 +0000125 ModuleSP module_sp (section->GetModule());
126 if (module_sp)
Greg Clayton9d192e12012-07-31 00:31:32 +0000127 {
Greg Claytonfd814c52013-08-13 01:42:25 +0000128 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 }
Greg Clayton9d192e12012-07-31 00:31:32 +0000138 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000139 }
Greg Claytonfd814c52013-08-13 01:42:25 +0000140 ats_pos->second = section;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000141 }
Greg Claytonfd814c52013-08-13 01:42:25 +0000142 else
143 m_addr_to_sect[load_addr] = section;
144 return true; // Changed
145
Greg Clayton10177aa2010-12-08 05:08:21 +0000146 }
Greg Clayton6d093452011-02-05 02:25:06 +0000147 else
Greg Claytonfd814c52013-08-13 01:42:25 +0000148 {
149 if (log)
150 {
151 log->Printf ("SectionLoadList::%s (section = %p (%s), load_addr = 0x%16.16" PRIx64 ") error: module has been deleted",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000152 __FUNCTION__, static_cast<void*>(section.get()),
Greg Claytonfd814c52013-08-13 01:42:25 +0000153 section->GetName().AsCString(),
154 load_addr);
155 }
156 }
157 return false;
Greg Clayton17f69202010-09-14 23:52:43 +0000158}
159
160size_t
Greg Clayton7820bd12012-07-07 01:24:12 +0000161SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp)
Greg Clayton17f69202010-09-14 23:52:43 +0000162{
Greg Clayton17f69202010-09-14 23:52:43 +0000163 size_t unload_count = 0;
Greg Clayton6d093452011-02-05 02:25:06 +0000164
Greg Clayton7820bd12012-07-07 01:24:12 +0000165 if (section_sp)
166 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000167 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
Greg Clayton7820bd12012-07-07 01:24:12 +0000168
169 if (log)
170 {
Jim Inghamcbff63a2016-01-29 20:21:33 +0000171 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 }
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000178 log->Printf ("SectionLoadList::%s (section = %p (%s.%s))",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000179 __FUNCTION__, static_cast<void*>(section_sp.get()),
Jim Inghamcbff63a2016-01-29 20:21:33 +0000180 module_name.c_str(),
Greg Clayton7820bd12012-07-07 01:24:12 +0000181 section_sp->GetName().AsCString());
182 }
183
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000184 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000185
Greg Clayton7820bd12012-07-07 01:24:12 +0000186 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 {
Greg Clayton3c947372013-01-29 01:17:09 +0000189 ++unload_count;
Greg Clayton7820bd12012-07-07 01:24:12 +0000190 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 }
Greg Clayton6d093452011-02-05 02:25:06 +0000197 }
Greg Clayton17f69202010-09-14 23:52:43 +0000198 return unload_count;
199}
200
201bool
Greg Clayton7820bd12012-07-07 01:24:12 +0000202SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp, addr_t load_addr)
Greg Clayton17f69202010-09-14 23:52:43 +0000203{
Greg Clayton5160ce52013-03-27 23:08:40 +0000204 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
Greg Clayton17f69202010-09-14 23:52:43 +0000205
206 if (log)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000207 {
Jim Inghamcbff63a2016-01-29 20:21:33 +0000208 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 }
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000215 log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ")",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000216 __FUNCTION__, static_cast<void*>(section_sp.get()),
Jim Inghamcbff63a2016-01-29 20:21:33 +0000217 module_name.c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000218 section_sp->GetName().AsCString(), load_addr);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000219 }
Greg Clayton6d093452011-02-05 02:25:06 +0000220 bool erased = false;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000221 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7820bd12012-07-07 01:24:12 +0000222 sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
Greg Clayton6d093452011-02-05 02:25:06 +0000223 if (sta_pos != m_sect_to_addr.end())
224 {
225 erased = true;
226 m_sect_to_addr.erase (sta_pos);
227 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000228
Greg Clayton6d093452011-02-05 02:25:06 +0000229 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;
Greg Clayton17f69202010-09-14 23:52:43 +0000237}
238
239
240bool
241SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const
242{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000243 // First find the top level section that this load address exists in
244 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Claytonc5e9a7d2011-05-17 18:13:59 +0000245 if (!m_addr_to_sect.empty())
Greg Clayton17f69202010-09-14 23:52:43 +0000246 {
Greg Claytonc5e9a7d2011-05-17 18:13:59 +0000247 addr_to_sect_collection::const_iterator pos = m_addr_to_sect.lower_bound (load_addr);
248 if (pos != m_addr_to_sect.end())
Greg Clayton17f69202010-09-14 23:52:43 +0000249 {
Greg Claytonc5e9a7d2011-05-17 18:13:59 +0000250 if (load_addr != pos->first && pos != m_addr_to_sect.begin())
251 --pos;
Greg Clayton39f7ee82013-02-01 21:38:35 +0000252 const addr_t pos_load_addr = pos->first;
253 if (load_addr >= pos_load_addr)
Jason Molendaf830e482010-12-22 02:02:45 +0000254 {
Greg Clayton39f7ee82013-02-01 21:38:35 +0000255 addr_t offset = load_addr - pos_load_addr;
Greg Claytonc5e9a7d2011-05-17 18:13:59 +0000256 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 {
Greg Clayton1c870d62011-05-18 18:22:47 +0000266 // 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)
Greg Claytonc5e9a7d2011-05-17 18:13:59 +0000270 {
Greg Clayton1c870d62011-05-18 18:22:47 +0000271 addr_t offset = load_addr - rpos->first;
272 if (offset < rpos->second->GetByteSize())
Greg Claytonc5e9a7d2011-05-17 18:13:59 +0000273 {
274 // We have found the top level section, now we need to find the
275 // deepest child section.
Greg Clayton1c870d62011-05-18 18:22:47 +0000276 return rpos->second->ResolveContainedAddress (offset, so_addr);
Greg Claytonc5e9a7d2011-05-17 18:13:59 +0000277 }
Jason Molendaf830e482010-12-22 02:02:45 +0000278 }
Greg Clayton17f69202010-09-14 23:52:43 +0000279 }
280 }
281 so_addr.Clear();
282 return false;
283}
Greg Clayton10177aa2010-12-08 05:08:21 +0000284
285void
286SectionLoadList::Dump (Stream &s, Target *target)
287{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000288 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton6d093452011-02-05 02:25:06 +0000289 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)
Greg Clayton10177aa2010-12-08 05:08:21 +0000291 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000292 s.Printf("addr = 0x%16.16" PRIx64 ", section = %p: ",
293 pos->first, static_cast<void*>(pos->second.get()));
Greg Clayton10177aa2010-12-08 05:08:21 +0000294 pos->second->Dump (&s, target, 0);
295 }
296}
297
298