]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/Section.cpp
Update llvm/clang to r240225.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / Section.cpp
1 //===-- Section.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/Core/Section.h"
11 #include "lldb/Core/Module.h"
12 #include "lldb/Symbol/ObjectFile.h"
13 #include "lldb/Target/SectionLoadList.h"
14 #include "lldb/Target/Target.h"
15
16 #include <limits>
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 Section::Section (const ModuleSP &module_sp,
22                   ObjectFile *obj_file,
23                   user_id_t sect_id,
24                   const ConstString &name,
25                   SectionType sect_type,
26                   addr_t file_addr,
27                   addr_t byte_size,
28                   lldb::offset_t file_offset,
29                   lldb::offset_t file_size,
30                   uint32_t log2align,
31                   uint32_t flags,
32                   uint32_t target_byte_size/*=1*/) :
33     ModuleChild     (module_sp),
34     UserID          (sect_id),
35     Flags           (flags),
36     m_obj_file      (obj_file),
37     m_type          (sect_type),
38     m_parent_wp     (),
39     m_name          (name),
40     m_file_addr     (file_addr),
41     m_byte_size     (byte_size),
42     m_file_offset   (file_offset),
43     m_file_size     (file_size),
44     m_log2align     (log2align),
45     m_children      (),
46     m_fake          (false),
47     m_encrypted     (false),
48     m_thread_specific (false),
49     m_target_byte_size(target_byte_size)
50 {
51 //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
52 //            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
53 }
54
55 Section::Section (const lldb::SectionSP &parent_section_sp,
56                   const ModuleSP &module_sp,
57                   ObjectFile *obj_file,
58                   user_id_t sect_id,
59                   const ConstString &name,
60                   SectionType sect_type,
61                   addr_t file_addr,
62                   addr_t byte_size,
63                   lldb::offset_t file_offset,
64                   lldb::offset_t file_size,
65                   uint32_t log2align,
66                   uint32_t flags,
67                   uint32_t target_byte_size/*=1*/) :
68     ModuleChild     (module_sp),
69     UserID          (sect_id),
70     Flags           (flags),
71     m_obj_file      (obj_file),
72     m_type          (sect_type),
73     m_parent_wp     (),
74     m_name          (name),
75     m_file_addr     (file_addr),
76     m_byte_size     (byte_size),
77     m_file_offset   (file_offset),
78     m_file_size     (file_size),
79     m_log2align     (log2align),
80     m_children      (),
81     m_fake          (false),
82     m_encrypted     (false),
83     m_thread_specific (false),
84     m_target_byte_size(target_byte_size)
85 {
86 //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
87 //            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
88     if (parent_section_sp)
89         m_parent_wp = parent_section_sp;
90 }
91
92 Section::~Section()
93 {
94 //    printf ("Section::~Section(%p)\n", this);
95 }
96
97 addr_t
98 Section::GetFileAddress () const
99 {
100     SectionSP parent_sp (GetParent ());
101     if (parent_sp)
102     {
103         // This section has a parent which means m_file_addr is an offset into
104         // the parent section, so the file address for this section is the file
105         // address of the parent plus the offset
106         return parent_sp->GetFileAddress() + m_file_addr;
107     }
108     // This section has no parent, so m_file_addr is the file base address
109     return m_file_addr;
110 }
111
112 bool
113 Section::SetFileAddress (lldb::addr_t file_addr)
114 {
115     SectionSP parent_sp (GetParent ());
116     if (parent_sp)
117     {
118         if (m_file_addr >= file_addr)
119             return parent_sp->SetFileAddress (m_file_addr - file_addr);
120         return false;
121     }
122     else
123     {
124         // This section has no parent, so m_file_addr is the file base address
125         m_file_addr = file_addr;
126         return true;
127     }
128 }
129
130 lldb::addr_t
131 Section::GetOffset () const
132 {
133     // This section has a parent which means m_file_addr is an offset.
134     SectionSP parent_sp (GetParent ());
135     if (parent_sp)
136         return m_file_addr;
137     
138     // This section has no parent, so there is no offset to be had
139     return 0;
140 }
141
142 addr_t
143 Section::GetLoadBaseAddress (Target *target) const
144 {
145     addr_t load_base_addr = LLDB_INVALID_ADDRESS;
146     SectionSP parent_sp (GetParent ());
147     if (parent_sp)
148     {
149         load_base_addr = parent_sp->GetLoadBaseAddress (target);
150         if (load_base_addr != LLDB_INVALID_ADDRESS)
151             load_base_addr += GetOffset();
152     }
153     if (load_base_addr == LLDB_INVALID_ADDRESS)
154     {
155         load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
156     }
157     return load_base_addr;
158 }
159
160 bool
161 Section::ResolveContainedAddress (addr_t offset, Address &so_addr) const
162 {
163     const size_t num_children = m_children.GetSize();
164     if (num_children > 0)
165     {
166         for (size_t i=0; i<num_children; i++)
167         {
168             Section* child_section = m_children.GetSectionAtIndex (i).get();
169
170             addr_t child_offset = child_section->GetOffset();
171             if (child_offset <= offset && offset - child_offset < child_section->GetByteSize())
172                 return child_section->ResolveContainedAddress (offset - child_offset, so_addr);
173         }
174     }
175     so_addr.SetOffset(offset);
176     so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
177     
178 #ifdef LLDB_CONFIGURATION_DEBUG
179     // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
180     assert(GetModule().get());
181 #endif
182     return true;
183 }
184
185 bool
186 Section::ContainsFileAddress (addr_t vm_addr) const
187 {
188     const addr_t file_addr = GetFileAddress();
189     if (file_addr != LLDB_INVALID_ADDRESS)
190     {
191         if (file_addr <= vm_addr)
192         {
193             const addr_t offset = (vm_addr - file_addr) *  m_target_byte_size;
194             return offset < GetByteSize();
195         }
196     }
197     return false;
198 }
199
200 int
201 Section::Compare (const Section& a, const Section& b)
202 {
203     if (&a == &b)
204         return 0;
205
206     const ModuleSP a_module_sp = a.GetModule();
207     const ModuleSP b_module_sp = b.GetModule();
208     if (a_module_sp == b_module_sp)
209     {
210         user_id_t a_sect_uid = a.GetID();
211         user_id_t b_sect_uid = b.GetID();
212         if (a_sect_uid < b_sect_uid)
213             return -1;
214         if (a_sect_uid > b_sect_uid)
215             return 1;
216         return 0;
217     }
218     else
219     {
220         // The modules are different, just compare the module pointers
221         if (a_module_sp.get() < b_module_sp.get())
222             return -1;
223         else
224             return 1;   // We already know the modules aren't equal
225     }
226 }
227
228
229 void
230 Section::Dump (Stream *s, Target *target, uint32_t depth) const
231 {
232 //    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
233     s->Indent();
234     s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetSectionTypeAsCString (m_type));
235     bool resolved = true;
236     addr_t addr = LLDB_INVALID_ADDRESS;
237
238     if (GetByteSize() == 0)
239         s->Printf("%39s", "");
240     else
241     {
242         if (target)
243             addr = GetLoadBaseAddress (target);
244
245         if (addr == LLDB_INVALID_ADDRESS)
246         {
247             if (target)
248                 resolved = false;
249             addr = GetFileAddress();
250         }
251
252         VMRange range(addr, addr + m_byte_size);
253         range.Dump (s, 0);
254     }
255
256     s->Printf("%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_file_offset, m_file_size, Get());
257
258     DumpName (s);
259
260     s->EOL();
261
262     if (depth > 0)
263         m_children.Dump(s, target, false, depth - 1);
264 }
265
266 void
267 Section::DumpName (Stream *s) const
268 {
269     SectionSP parent_sp (GetParent ());
270     if (parent_sp)
271     {
272         parent_sp->DumpName (s);
273         s->PutChar('.');
274     }
275     else
276     {
277         // The top most section prints the module basename
278         const char * name = NULL;
279         ModuleSP module_sp (GetModule());
280         const FileSpec &file_spec = m_obj_file->GetFileSpec();
281
282         if (m_obj_file)
283             name = file_spec.GetFilename().AsCString();
284         if ((!name || !name[0]) && module_sp)
285             name = module_sp->GetFileSpec().GetFilename().AsCString();
286         if (name && name[0])
287             s->Printf("%s.", name);
288     }
289     m_name.Dump(s);
290 }
291
292 bool
293 Section::IsDescendant (const Section *section)
294 {
295     if (this == section)
296         return true;
297     SectionSP parent_sp (GetParent ());
298     if (parent_sp)
299         return parent_sp->IsDescendant (section);
300     return false;
301 }
302
303 bool
304 Section::Slide (addr_t slide_amount, bool slide_children)
305 {
306     if (m_file_addr != LLDB_INVALID_ADDRESS)
307     {
308         if (slide_amount == 0)
309             return true;
310
311         m_file_addr += slide_amount;
312
313         if (slide_children)
314             m_children.Slide (slide_amount, slide_children);
315
316         return true;
317     }
318     return false;
319 }
320
321 #pragma mark SectionList
322
323 SectionList::SectionList () :
324     m_sections()
325 {
326 }
327
328
329 SectionList::~SectionList ()
330 {
331 }
332
333 SectionList &
334 SectionList::operator = (const SectionList& rhs)
335 {
336     if (this != &rhs)
337         m_sections = rhs.m_sections;
338     return *this;
339 }
340
341 size_t
342 SectionList::AddSection (const lldb::SectionSP& section_sp)
343 {
344     if (section_sp)
345     {
346         size_t section_index = m_sections.size();
347         m_sections.push_back(section_sp);
348         return section_index;
349     }
350
351     return std::numeric_limits<size_t>::max ();
352 }
353
354 // Warning, this can be slow as it's removing items from a std::vector.
355 bool
356 SectionList::DeleteSection (size_t idx)
357 {
358     if (idx < m_sections.size())
359     {
360         m_sections.erase (m_sections.begin() + idx);
361         return true; 
362     }
363     return false;
364 }
365
366 size_t
367 SectionList::FindSectionIndex (const Section* sect)
368 {
369     iterator sect_iter;
370     iterator begin = m_sections.begin();
371     iterator end = m_sections.end();
372     for (sect_iter = begin; sect_iter != end; ++sect_iter)
373     {
374         if (sect_iter->get() == sect)
375         {
376             // The secton was already in this section list
377             return std::distance (begin, sect_iter);
378         }
379     }
380     return UINT32_MAX;
381 }
382
383 size_t
384 SectionList::AddUniqueSection (const lldb::SectionSP& sect_sp)
385 {
386     size_t sect_idx = FindSectionIndex (sect_sp.get());
387     if (sect_idx == UINT32_MAX)
388     {
389         sect_idx = AddSection (sect_sp);
390     }
391     return sect_idx;
392 }
393
394 bool
395 SectionList::ReplaceSection (user_id_t sect_id, const lldb::SectionSP& sect_sp, uint32_t depth)
396 {
397     iterator sect_iter, end = m_sections.end();
398     for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
399     {
400         if ((*sect_iter)->GetID() == sect_id)
401         {
402             *sect_iter = sect_sp;
403             return true;
404         }
405         else if (depth > 0)
406         {
407             if ((*sect_iter)->GetChildren().ReplaceSection(sect_id, sect_sp, depth - 1))
408                 return true;
409         }
410     }
411     return false;
412 }
413
414 size_t
415 SectionList::GetNumSections (uint32_t depth) const
416 {
417     size_t count = m_sections.size();
418     if (depth > 0)
419     {
420         const_iterator sect_iter, end = m_sections.end();
421         for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
422         {
423             count += (*sect_iter)->GetChildren().GetNumSections(depth - 1);
424         }
425     }
426     return count;
427 }
428
429 SectionSP
430 SectionList::GetSectionAtIndex (size_t idx) const
431 {
432     SectionSP sect_sp;
433     if (idx < m_sections.size())
434         sect_sp = m_sections[idx];
435     return sect_sp;
436 }
437
438 SectionSP
439 SectionList::FindSectionByName (const ConstString &section_dstr) const
440 {
441     SectionSP sect_sp;
442     // Check if we have a valid section string
443     if (section_dstr && !m_sections.empty())
444     {
445         const_iterator sect_iter;
446         const_iterator end = m_sections.end();
447         for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
448         {
449             Section *child_section = sect_iter->get();
450             if (child_section)
451             {
452                 if (child_section->GetName() == section_dstr)
453                 {
454                     sect_sp = *sect_iter;
455                 }
456                 else
457                 {
458                     sect_sp = child_section->GetChildren().FindSectionByName(section_dstr);
459                 }
460             }
461         }
462     }
463     return sect_sp;
464 }
465
466 SectionSP
467 SectionList::FindSectionByID (user_id_t sect_id) const
468 {
469     SectionSP sect_sp;
470     if (sect_id)
471     {
472         const_iterator sect_iter;
473         const_iterator end = m_sections.end();
474         for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
475         {
476             if ((*sect_iter)->GetID() == sect_id)
477             {
478                 sect_sp = *sect_iter;
479                 break;
480             }
481             else
482             {
483                 sect_sp = (*sect_iter)->GetChildren().FindSectionByID (sect_id);
484             }
485         }
486     }
487     return sect_sp;
488 }
489
490
491 SectionSP
492 SectionList::FindSectionByType (SectionType sect_type, bool check_children, size_t start_idx) const
493 {
494     SectionSP sect_sp;
495     size_t num_sections = m_sections.size();
496     for (size_t idx = start_idx; idx < num_sections; ++idx)
497     {
498         if (m_sections[idx]->GetType() == sect_type)
499         {
500             sect_sp = m_sections[idx];
501             break;
502         }
503         else if (check_children)
504         {
505             sect_sp = m_sections[idx]->GetChildren().FindSectionByType (sect_type, check_children, 0);
506             if (sect_sp)
507                 break;
508         }
509     }
510     return sect_sp;
511 }
512
513 SectionSP
514 SectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) const
515 {
516     SectionSP sect_sp;
517     const_iterator sect_iter;
518     const_iterator end = m_sections.end();
519     for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
520     {
521         Section *sect = sect_iter->get();
522         if (sect->ContainsFileAddress (vm_addr))
523         {
524             // The file address is in this section. We need to make sure one of our child
525             // sections doesn't contain this address as well as obeying the depth limit
526             // that was passed in.
527             if (depth > 0)
528                 sect_sp = sect->GetChildren().FindSectionContainingFileAddress(vm_addr, depth - 1);
529
530             if (sect_sp.get() == NULL && !sect->IsFake())
531                 sect_sp = *sect_iter;
532         }
533     }
534     return sect_sp;
535 }
536
537 bool
538 SectionList::ContainsSection(user_id_t sect_id) const
539 {
540     return FindSectionByID (sect_id).get() != NULL;
541 }
542
543 void
544 SectionList::Dump (Stream *s, Target *target, bool show_header, uint32_t depth) const
545 {
546     bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty();
547     if (show_header && !m_sections.empty())
548     {
549         s->Indent();
550         s->Printf(    "SectID     Type             %s Address                             File Off.  File Size  Flags      Section Name\n", target_has_loaded_sections ? "Load" : "File");
551         s->Indent();
552         s->PutCString("---------- ---------------- ---------------------------------------  ---------- ---------- ---------- ----------------------------\n");
553     }
554
555
556     const_iterator sect_iter;
557     const_iterator end = m_sections.end();
558     for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
559     {
560         (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL, depth);
561     }
562
563     if (show_header && !m_sections.empty())
564         s->IndentLess();
565
566 }
567
568 size_t
569 SectionList::Slide (addr_t slide_amount, bool slide_children)
570 {
571     size_t count = 0;
572     const_iterator pos, end = m_sections.end();
573     for (pos = m_sections.begin(); pos != end; ++pos)
574     {
575         if ((*pos)->Slide(slide_amount, slide_children))
576             ++count;
577     }
578     return count;
579 }