1ac7ddfbfSEd Maste //===-- SBSection.cpp -------------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/API/SBSection.h"
11ac7ddfbfSEd Maste #include "lldb/API/SBStream.h"
12ac7ddfbfSEd Maste #include "lldb/API/SBTarget.h"
13ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
14ac7ddfbfSEd Maste #include "lldb/Core/Section.h"
15ac7ddfbfSEd Maste #include "lldb/Symbol/ObjectFile.h"
16f678e45dSDimitry Andric #include "lldb/Utility/DataBuffer.h"
17f678e45dSDimitry Andric #include "lldb/Utility/DataExtractor.h"
18f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
19f678e45dSDimitry Andric #include "lldb/Utility/StreamString.h"
20ac7ddfbfSEd Maste 
21ac7ddfbfSEd Maste using namespace lldb;
22ac7ddfbfSEd Maste using namespace lldb_private;
23ac7ddfbfSEd Maste 
SBSection()24435933ddSDimitry Andric SBSection::SBSection() : m_opaque_wp() {}
25ac7ddfbfSEd Maste 
SBSection(const SBSection & rhs)26435933ddSDimitry Andric SBSection::SBSection(const SBSection &rhs) : m_opaque_wp(rhs.m_opaque_wp) {}
27ac7ddfbfSEd Maste 
SBSection(const lldb::SectionSP & section_sp)28435933ddSDimitry Andric SBSection::SBSection(const lldb::SectionSP &section_sp)
29435933ddSDimitry Andric     : m_opaque_wp() // Don't init with section_sp otherwise this will throw if
30435933ddSDimitry Andric                     // section_sp doesn't contain a valid Section *
31ac7ddfbfSEd Maste {
32ac7ddfbfSEd Maste   if (section_sp)
33ac7ddfbfSEd Maste     m_opaque_wp = section_sp;
34ac7ddfbfSEd Maste }
35ac7ddfbfSEd Maste 
operator =(const SBSection & rhs)36435933ddSDimitry Andric const SBSection &SBSection::operator=(const SBSection &rhs) {
37ac7ddfbfSEd Maste   m_opaque_wp = rhs.m_opaque_wp;
38ac7ddfbfSEd Maste   return *this;
39ac7ddfbfSEd Maste }
40ac7ddfbfSEd Maste 
~SBSection()41435933ddSDimitry Andric SBSection::~SBSection() {}
42ac7ddfbfSEd Maste 
IsValid() const43435933ddSDimitry Andric bool SBSection::IsValid() const {
44ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
45ac7ddfbfSEd Maste   return section_sp && section_sp->GetModule().get() != NULL;
46ac7ddfbfSEd Maste }
47ac7ddfbfSEd Maste 
GetName()48435933ddSDimitry Andric const char *SBSection::GetName() {
49ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
50ac7ddfbfSEd Maste   if (section_sp)
51ac7ddfbfSEd Maste     return section_sp->GetName().GetCString();
52ac7ddfbfSEd Maste   return NULL;
53ac7ddfbfSEd Maste }
54ac7ddfbfSEd Maste 
GetParent()55435933ddSDimitry Andric lldb::SBSection SBSection::GetParent() {
56ac7ddfbfSEd Maste   lldb::SBSection sb_section;
57ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
58435933ddSDimitry Andric   if (section_sp) {
59ac7ddfbfSEd Maste     SectionSP parent_section_sp(section_sp->GetParent());
60ac7ddfbfSEd Maste     if (parent_section_sp)
61ac7ddfbfSEd Maste       sb_section.SetSP(parent_section_sp);
62ac7ddfbfSEd Maste   }
63ac7ddfbfSEd Maste   return sb_section;
64ac7ddfbfSEd Maste }
65ac7ddfbfSEd Maste 
FindSubSection(const char * sect_name)66435933ddSDimitry Andric lldb::SBSection SBSection::FindSubSection(const char *sect_name) {
67ac7ddfbfSEd Maste   lldb::SBSection sb_section;
68435933ddSDimitry Andric   if (sect_name) {
69ac7ddfbfSEd Maste     SectionSP section_sp(GetSP());
70435933ddSDimitry Andric     if (section_sp) {
71ac7ddfbfSEd Maste       ConstString const_sect_name(sect_name);
72435933ddSDimitry Andric       sb_section.SetSP(
73435933ddSDimitry Andric           section_sp->GetChildren().FindSectionByName(const_sect_name));
74ac7ddfbfSEd Maste     }
75ac7ddfbfSEd Maste   }
76ac7ddfbfSEd Maste   return sb_section;
77ac7ddfbfSEd Maste }
78ac7ddfbfSEd Maste 
GetNumSubSections()79435933ddSDimitry Andric size_t SBSection::GetNumSubSections() {
80ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
81ac7ddfbfSEd Maste   if (section_sp)
82ac7ddfbfSEd Maste     return section_sp->GetChildren().GetSize();
83ac7ddfbfSEd Maste   return 0;
84ac7ddfbfSEd Maste }
85ac7ddfbfSEd Maste 
GetSubSectionAtIndex(size_t idx)86435933ddSDimitry Andric lldb::SBSection SBSection::GetSubSectionAtIndex(size_t idx) {
87ac7ddfbfSEd Maste   lldb::SBSection sb_section;
88ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
89ac7ddfbfSEd Maste   if (section_sp)
90ac7ddfbfSEd Maste     sb_section.SetSP(section_sp->GetChildren().GetSectionAtIndex(idx));
91ac7ddfbfSEd Maste   return sb_section;
92ac7ddfbfSEd Maste }
93ac7ddfbfSEd Maste 
GetSP() const94435933ddSDimitry Andric lldb::SectionSP SBSection::GetSP() const { return m_opaque_wp.lock(); }
95ac7ddfbfSEd Maste 
SetSP(const lldb::SectionSP & section_sp)96435933ddSDimitry Andric void SBSection::SetSP(const lldb::SectionSP &section_sp) {
97ac7ddfbfSEd Maste   m_opaque_wp = section_sp;
98ac7ddfbfSEd Maste }
99ac7ddfbfSEd Maste 
GetFileAddress()100435933ddSDimitry Andric lldb::addr_t SBSection::GetFileAddress() {
101ac7ddfbfSEd Maste   lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
102ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
103ac7ddfbfSEd Maste   if (section_sp)
104ac7ddfbfSEd Maste     return section_sp->GetFileAddress();
105ac7ddfbfSEd Maste   return file_addr;
106ac7ddfbfSEd Maste }
107ac7ddfbfSEd Maste 
GetLoadAddress(lldb::SBTarget & sb_target)108435933ddSDimitry Andric lldb::addr_t SBSection::GetLoadAddress(lldb::SBTarget &sb_target) {
109ac7ddfbfSEd Maste   TargetSP target_sp(sb_target.GetSP());
110435933ddSDimitry Andric   if (target_sp) {
111ac7ddfbfSEd Maste     SectionSP section_sp(GetSP());
112ac7ddfbfSEd Maste     if (section_sp)
113ac7ddfbfSEd Maste       return section_sp->GetLoadBaseAddress(target_sp.get());
114ac7ddfbfSEd Maste   }
115ac7ddfbfSEd Maste   return LLDB_INVALID_ADDRESS;
116ac7ddfbfSEd Maste }
117ac7ddfbfSEd Maste 
GetByteSize()118435933ddSDimitry Andric lldb::addr_t SBSection::GetByteSize() {
119ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
120ac7ddfbfSEd Maste   if (section_sp)
121ac7ddfbfSEd Maste     return section_sp->GetByteSize();
122ac7ddfbfSEd Maste   return 0;
123ac7ddfbfSEd Maste }
124ac7ddfbfSEd Maste 
GetFileOffset()125435933ddSDimitry Andric uint64_t SBSection::GetFileOffset() {
126ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
127435933ddSDimitry Andric   if (section_sp) {
128ac7ddfbfSEd Maste     ModuleSP module_sp(section_sp->GetModule());
129435933ddSDimitry Andric     if (module_sp) {
130ac7ddfbfSEd Maste       ObjectFile *objfile = module_sp->GetObjectFile();
131ac7ddfbfSEd Maste       if (objfile)
132ac7ddfbfSEd Maste         return objfile->GetFileOffset() + section_sp->GetFileOffset();
133ac7ddfbfSEd Maste     }
134ac7ddfbfSEd Maste   }
135ac7ddfbfSEd Maste   return UINT64_MAX;
136ac7ddfbfSEd Maste }
137ac7ddfbfSEd Maste 
GetFileByteSize()138435933ddSDimitry Andric uint64_t SBSection::GetFileByteSize() {
139ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
140ac7ddfbfSEd Maste   if (section_sp)
141ac7ddfbfSEd Maste     return section_sp->GetFileSize();
142ac7ddfbfSEd Maste   return 0;
143ac7ddfbfSEd Maste }
144ac7ddfbfSEd Maste 
GetSectionData()145435933ddSDimitry Andric SBData SBSection::GetSectionData() { return GetSectionData(0, UINT64_MAX); }
146ac7ddfbfSEd Maste 
GetSectionData(uint64_t offset,uint64_t size)147435933ddSDimitry Andric SBData SBSection::GetSectionData(uint64_t offset, uint64_t size) {
148ac7ddfbfSEd Maste   SBData sb_data;
149ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
150435933ddSDimitry Andric   if (section_sp) {
151ac7ddfbfSEd Maste     const uint64_t sect_file_size = section_sp->GetFileSize();
152435933ddSDimitry Andric     if (sect_file_size > 0) {
153ac7ddfbfSEd Maste       ModuleSP module_sp(section_sp->GetModule());
154435933ddSDimitry Andric       if (module_sp) {
155ac7ddfbfSEd Maste         ObjectFile *objfile = module_sp->GetObjectFile();
156435933ddSDimitry Andric         if (objfile) {
157435933ddSDimitry Andric           const uint64_t sect_file_offset =
158435933ddSDimitry Andric               objfile->GetFileOffset() + section_sp->GetFileOffset();
159ac7ddfbfSEd Maste           const uint64_t file_offset = sect_file_offset + offset;
160ac7ddfbfSEd Maste           uint64_t file_size = size;
161435933ddSDimitry Andric           if (file_size == UINT64_MAX) {
162ac7ddfbfSEd Maste             file_size = section_sp->GetByteSize();
163ac7ddfbfSEd Maste             if (file_size > offset)
164ac7ddfbfSEd Maste               file_size -= offset;
165ac7ddfbfSEd Maste             else
166ac7ddfbfSEd Maste               file_size = 0;
167ac7ddfbfSEd Maste           }
168*b5893f02SDimitry Andric           auto data_buffer_sp = FileSystem::Instance().CreateDataBuffer(
169f678e45dSDimitry Andric               objfile->GetFileSpec().GetPath(), file_size, file_offset);
170435933ddSDimitry Andric           if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) {
171435933ddSDimitry Andric             DataExtractorSP data_extractor_sp(
172435933ddSDimitry Andric                 new DataExtractor(data_buffer_sp, objfile->GetByteOrder(),
173ac7ddfbfSEd Maste                                   objfile->GetAddressByteSize()));
174ac7ddfbfSEd Maste 
175ac7ddfbfSEd Maste             sb_data.SetOpaque(data_extractor_sp);
176ac7ddfbfSEd Maste           }
177ac7ddfbfSEd Maste         }
178ac7ddfbfSEd Maste       }
179ac7ddfbfSEd Maste     }
180ac7ddfbfSEd Maste   }
181ac7ddfbfSEd Maste   return sb_data;
182ac7ddfbfSEd Maste }
183ac7ddfbfSEd Maste 
GetSectionType()184435933ddSDimitry Andric SectionType SBSection::GetSectionType() {
185ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
186ac7ddfbfSEd Maste   if (section_sp.get())
187ac7ddfbfSEd Maste     return section_sp->GetType();
188ac7ddfbfSEd Maste   return eSectionTypeInvalid;
189ac7ddfbfSEd Maste }
190ac7ddfbfSEd Maste 
1917aa51b79SEd Maste uint32_t
GetPermissions() const192435933ddSDimitry Andric SBSection::GetPermissions() const
1937aa51b79SEd Maste {
1947aa51b79SEd Maste     SectionSP section_sp(GetSP());
195435933ddSDimitry Andric     if (section_sp)
196435933ddSDimitry Andric         return section_sp->GetPermissions();
197435933ddSDimitry Andric     return 0;
198435933ddSDimitry Andric }
199435933ddSDimitry Andric 
GetTargetByteSize()200435933ddSDimitry Andric uint32_t SBSection::GetTargetByteSize() {
201435933ddSDimitry Andric   SectionSP section_sp(GetSP());
2027aa51b79SEd Maste   if (section_sp.get())
2037aa51b79SEd Maste     return section_sp->GetTargetByteSize();
2047aa51b79SEd Maste   return 0;
2057aa51b79SEd Maste }
206ac7ddfbfSEd Maste 
operator ==(const SBSection & rhs)207435933ddSDimitry Andric bool SBSection::operator==(const SBSection &rhs) {
208ac7ddfbfSEd Maste   SectionSP lhs_section_sp(GetSP());
209ac7ddfbfSEd Maste   SectionSP rhs_section_sp(rhs.GetSP());
210ac7ddfbfSEd Maste   if (lhs_section_sp && rhs_section_sp)
211ac7ddfbfSEd Maste     return lhs_section_sp == rhs_section_sp;
212ac7ddfbfSEd Maste   return false;
213ac7ddfbfSEd Maste }
214ac7ddfbfSEd Maste 
operator !=(const SBSection & rhs)215435933ddSDimitry Andric bool SBSection::operator!=(const SBSection &rhs) {
216ac7ddfbfSEd Maste   SectionSP lhs_section_sp(GetSP());
217ac7ddfbfSEd Maste   SectionSP rhs_section_sp(rhs.GetSP());
218ac7ddfbfSEd Maste   return lhs_section_sp != rhs_section_sp;
219ac7ddfbfSEd Maste }
220ac7ddfbfSEd Maste 
GetDescription(SBStream & description)221435933ddSDimitry Andric bool SBSection::GetDescription(SBStream &description) {
222ac7ddfbfSEd Maste   Stream &strm = description.ref();
223ac7ddfbfSEd Maste 
224ac7ddfbfSEd Maste   SectionSP section_sp(GetSP());
225435933ddSDimitry Andric   if (section_sp) {
226ac7ddfbfSEd Maste     const addr_t file_addr = section_sp->GetFileAddress();
227435933ddSDimitry Andric     strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr,
228435933ddSDimitry Andric                 file_addr + section_sp->GetByteSize());
229ac7ddfbfSEd Maste     section_sp->DumpName(&strm);
230435933ddSDimitry Andric   } else {
231ac7ddfbfSEd Maste     strm.PutCString("No value");
232ac7ddfbfSEd Maste   }
233ac7ddfbfSEd Maste 
234ac7ddfbfSEd Maste   return true;
235ac7ddfbfSEd Maste }
236