1//===-- SBSection.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/API/SBSection.h"
11#include "lldb/API/SBStream.h"
12#include "lldb/API/SBTarget.h"
13#include "lldb/Core/DataBuffer.h"
14#include "lldb/Core/DataExtractor.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/Module.h"
17#include "lldb/Core/Section.h"
18#include "lldb/Core/StreamString.h"
19#include "lldb/Symbol/ObjectFile.h"
20
21
22using namespace lldb;
23using namespace lldb_private;
24
25
26SBSection::SBSection () :
27    m_opaque_wp ()
28{
29}
30
31SBSection::SBSection (const SBSection &rhs) :
32    m_opaque_wp (rhs.m_opaque_wp)
33{
34}
35
36
37
38SBSection::SBSection (const lldb::SectionSP &section_sp) :
39    m_opaque_wp () // Don't init with section_sp otherwise this will throw if section_sp doesn't contain a valid Section *
40{
41    if (section_sp)
42        m_opaque_wp = section_sp;
43}
44
45const SBSection &
46SBSection::operator = (const SBSection &rhs)
47{
48    m_opaque_wp = rhs.m_opaque_wp;
49    return *this;
50}
51
52SBSection::~SBSection ()
53{
54}
55
56bool
57SBSection::IsValid () const
58{
59    SectionSP section_sp (GetSP());
60    return section_sp && section_sp->GetModule().get() != NULL;
61}
62
63const char *
64SBSection::GetName ()
65{
66    SectionSP section_sp (GetSP());
67    if (section_sp)
68        return section_sp->GetName().GetCString();
69    return NULL;
70}
71
72lldb::SBSection
73SBSection::GetParent()
74{
75    lldb::SBSection sb_section;
76    SectionSP section_sp (GetSP());
77    if (section_sp)
78    {
79        SectionSP parent_section_sp (section_sp->GetParent());
80        if (parent_section_sp)
81            sb_section.SetSP(parent_section_sp);
82    }
83    return sb_section;
84}
85
86
87lldb::SBSection
88SBSection::FindSubSection (const char *sect_name)
89{
90    lldb::SBSection sb_section;
91    if (sect_name)
92    {
93        SectionSP section_sp (GetSP());
94        if (section_sp)
95        {
96            ConstString const_sect_name(sect_name);
97            sb_section.SetSP(section_sp->GetChildren ().FindSectionByName(const_sect_name));
98        }
99    }
100    return sb_section;
101}
102
103size_t
104SBSection::GetNumSubSections ()
105{
106    SectionSP section_sp (GetSP());
107    if (section_sp)
108        return section_sp->GetChildren ().GetSize();
109    return 0;
110}
111
112lldb::SBSection
113SBSection::GetSubSectionAtIndex (size_t idx)
114{
115    lldb::SBSection sb_section;
116    SectionSP section_sp (GetSP());
117    if (section_sp)
118        sb_section.SetSP (section_sp->GetChildren ().GetSectionAtIndex(idx));
119    return sb_section;
120}
121
122lldb::SectionSP
123SBSection::GetSP() const
124{
125    return m_opaque_wp.lock();
126}
127
128void
129SBSection::SetSP(const lldb::SectionSP &section_sp)
130{
131    m_opaque_wp = section_sp;
132}
133
134lldb::addr_t
135SBSection::GetFileAddress ()
136{
137    lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
138    SectionSP section_sp (GetSP());
139    if (section_sp)
140        return section_sp->GetFileAddress();
141    return file_addr;
142}
143
144lldb::addr_t
145SBSection::GetLoadAddress (lldb::SBTarget &sb_target)
146{
147    TargetSP target_sp(sb_target.GetSP());
148    if (target_sp)
149    {
150        SectionSP section_sp (GetSP());
151        if (section_sp)
152            return section_sp->GetLoadBaseAddress(target_sp.get());
153    }
154    return LLDB_INVALID_ADDRESS;
155
156}
157
158
159
160lldb::addr_t
161SBSection::GetByteSize ()
162{
163    SectionSP section_sp (GetSP());
164    if (section_sp)
165        return section_sp->GetByteSize();
166    return 0;
167}
168
169uint64_t
170SBSection::GetFileOffset ()
171{
172    SectionSP section_sp (GetSP());
173    if (section_sp)
174    {
175        ModuleSP module_sp (section_sp->GetModule());
176        if (module_sp)
177        {
178            ObjectFile *objfile = module_sp->GetObjectFile();
179            if (objfile)
180                return objfile->GetFileOffset() + section_sp->GetFileOffset();
181        }
182    }
183    return UINT64_MAX;
184}
185
186uint64_t
187SBSection::GetFileByteSize ()
188{
189    SectionSP section_sp (GetSP());
190    if (section_sp)
191        return section_sp->GetFileSize();
192    return 0;
193}
194
195SBData
196SBSection::GetSectionData ()
197{
198    return GetSectionData (0, UINT64_MAX);
199}
200
201SBData
202SBSection::GetSectionData (uint64_t offset, uint64_t size)
203{
204    SBData sb_data;
205    SectionSP section_sp (GetSP());
206    if (section_sp)
207    {
208        const uint64_t sect_file_size = section_sp->GetFileSize();
209        if (sect_file_size > 0)
210        {
211            ModuleSP module_sp (section_sp->GetModule());
212            if (module_sp)
213            {
214                ObjectFile *objfile = module_sp->GetObjectFile();
215                if (objfile)
216                {
217                    const uint64_t sect_file_offset = objfile->GetFileOffset() + section_sp->GetFileOffset();
218                    const uint64_t file_offset = sect_file_offset + offset;
219                    uint64_t file_size = size;
220                    if (file_size == UINT64_MAX)
221                    {
222                        file_size = section_sp->GetByteSize();
223                        if (file_size > offset)
224                            file_size -= offset;
225                        else
226                            file_size = 0;
227                    }
228                    DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size));
229                    if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
230                    {
231                        DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp,
232                                                                              objfile->GetByteOrder(),
233                                                                              objfile->GetAddressByteSize()));
234
235                        sb_data.SetOpaque (data_extractor_sp);
236                    }
237                }
238            }
239        }
240    }
241    return sb_data;
242}
243
244SectionType
245SBSection::GetSectionType ()
246{
247    SectionSP section_sp (GetSP());
248    if (section_sp.get())
249        return section_sp->GetType();
250    return eSectionTypeInvalid;
251}
252
253
254bool
255SBSection::operator == (const SBSection &rhs)
256{
257    SectionSP lhs_section_sp (GetSP());
258    SectionSP rhs_section_sp (rhs.GetSP());
259    if (lhs_section_sp && rhs_section_sp)
260        return lhs_section_sp == rhs_section_sp;
261    return false;
262}
263
264bool
265SBSection::operator != (const SBSection &rhs)
266{
267    SectionSP lhs_section_sp (GetSP());
268    SectionSP rhs_section_sp (rhs.GetSP());
269    return lhs_section_sp != rhs_section_sp;
270}
271
272bool
273SBSection::GetDescription (SBStream &description)
274{
275    Stream &strm = description.ref();
276
277    SectionSP section_sp (GetSP());
278    if (section_sp)
279    {
280        const addr_t file_addr = section_sp->GetFileAddress();
281        strm.Printf ("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr, file_addr + section_sp->GetByteSize());
282        section_sp->DumpName(&strm);
283    }
284    else
285    {
286        strm.PutCString ("No value");
287    }
288
289    return true;
290}
291
292