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/Core/DataBuffer.h" 13 #include "lldb/Core/DataExtractor.h" 14 #include "lldb/Core/Log.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/Section.h" 17 #include "lldb/Core/StreamString.h" 18 19 namespace lldb_private 20 { 21 // We need a section implementation to hold onto a reference to the module 22 // since if the module goes away and we have anyone still holding onto a 23 // SBSection object, we could crash. 24 class SectionImpl 25 { 26 public: 27 SectionImpl (const lldb_private::Section *section = NULL) : 28 m_module_sp (), 29 m_section (section) 30 { 31 if (section) 32 m_module_sp = section->GetModule(); 33 } 34 35 SectionImpl (const SectionImpl &rhs) : 36 m_module_sp (rhs.m_module_sp), 37 m_section (rhs.m_section) 38 { 39 } 40 41 bool 42 IsValid () const 43 { 44 return m_section != NULL; 45 } 46 47 void 48 operator = (const SectionImpl &rhs) 49 { 50 m_module_sp = rhs.m_module_sp; 51 m_section = rhs.m_section; 52 } 53 54 void 55 operator =(const lldb_private::Section *section) 56 { 57 m_section = section; 58 if (section) 59 m_module_sp.reset(section->GetModule()); 60 else 61 m_module_sp.reset(); 62 } 63 64 const lldb_private::Section * 65 GetSection () const 66 { 67 return m_section; 68 } 69 70 Module * 71 GetModule() 72 { 73 return m_module_sp.get(); 74 } 75 76 const lldb::ModuleSP & 77 GetModuleSP() const 78 { 79 return m_module_sp; 80 } 81 protected: 82 lldb::ModuleSP m_module_sp; 83 const lldb_private::Section *m_section; 84 }; 85 } 86 87 using namespace lldb; 88 using namespace lldb_private; 89 90 91 SBSection::SBSection () : 92 m_opaque_ap () 93 { 94 } 95 96 SBSection::SBSection (const SBSection &rhs) : 97 m_opaque_ap () 98 { 99 if (rhs.IsValid()) 100 m_opaque_ap.reset (new SectionImpl (*rhs.m_opaque_ap)); 101 } 102 103 104 105 SBSection::SBSection (const lldb_private::Section *section) : 106 m_opaque_ap () 107 { 108 if (section) 109 m_opaque_ap.reset (new SectionImpl(section)); 110 } 111 112 const SBSection & 113 SBSection::operator = (const SBSection &rhs) 114 { 115 if (this != &rhs && rhs.IsValid()) 116 m_opaque_ap.reset (new SectionImpl(*rhs.m_opaque_ap)); 117 else 118 m_opaque_ap.reset (); 119 return *this; 120 } 121 122 SBSection::~SBSection () 123 { 124 } 125 126 bool 127 SBSection::IsValid () const 128 { 129 return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); 130 } 131 132 const char * 133 SBSection::GetName () 134 { 135 if (IsValid()) 136 return m_opaque_ap->GetSection()->GetName().GetCString(); 137 return NULL; 138 } 139 140 141 lldb::SBSection 142 SBSection::FindSubSection (const char *sect_name) 143 { 144 lldb::SBSection sb_section; 145 if (IsValid()) 146 { 147 ConstString const_sect_name(sect_name); 148 sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().FindSectionByName(const_sect_name).get()); 149 } 150 return sb_section; 151 } 152 153 size_t 154 SBSection::GetNumSubSections () 155 { 156 if (IsValid()) 157 return m_opaque_ap->GetSection()->GetChildren ().GetSize(); 158 return 0; 159 } 160 161 lldb::SBSection 162 SBSection::GetSubSectionAtIndex (size_t idx) 163 { 164 lldb::SBSection sb_section; 165 if (IsValid()) 166 sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().GetSectionAtIndex(idx).get()); 167 return sb_section; 168 } 169 170 const lldb_private::Section * 171 SBSection::GetSection() 172 { 173 if (m_opaque_ap.get()) 174 return m_opaque_ap->GetSection(); 175 return NULL; 176 } 177 178 void 179 SBSection::SetSection (const lldb_private::Section *section) 180 { 181 m_opaque_ap.reset (new SectionImpl(section)); 182 } 183 184 185 186 187 lldb::addr_t 188 SBSection::GetFileAddress () 189 { 190 lldb::addr_t file_addr = LLDB_INVALID_ADDRESS; 191 if (IsValid()) 192 return m_opaque_ap->GetSection()->GetFileAddress(); 193 return file_addr; 194 } 195 196 lldb::addr_t 197 SBSection::GetByteSize () 198 { 199 if (IsValid()) 200 { 201 const Section *section = m_opaque_ap->GetSection(); 202 if (section) 203 return section->GetByteSize(); 204 } 205 return 0; 206 } 207 208 uint64_t 209 SBSection::GetFileOffset () 210 { 211 if (IsValid()) 212 { 213 const Section *section = m_opaque_ap->GetSection(); 214 if (section) 215 { 216 Module *module = m_opaque_ap->GetModule(); 217 if (module) 218 { 219 ObjectFile *objfile = module->GetObjectFile(); 220 if (objfile) 221 return objfile->GetOffset() + section->GetFileOffset(); 222 } 223 return section->GetFileOffset(); 224 } 225 } 226 return 0; 227 } 228 229 uint64_t 230 SBSection::GetFileByteSize () 231 { 232 if (IsValid()) 233 { 234 const Section *section = m_opaque_ap->GetSection(); 235 if (section) 236 return section->GetFileSize(); 237 } 238 return 0; 239 } 240 241 SBData 242 SBSection::GetSectionData () 243 { 244 return GetSectionData (0, UINT64_MAX); 245 } 246 247 SBData 248 SBSection::GetSectionData (uint64_t offset, uint64_t size) 249 { 250 SBData sb_data; 251 if (IsValid()) 252 { 253 const Section *section = m_opaque_ap->GetSection(); 254 if (section) 255 { 256 const uint64_t sect_file_size = section->GetFileSize(); 257 if (sect_file_size > 0) 258 { 259 Module *module = m_opaque_ap->GetModule(); 260 if (module) 261 { 262 ObjectFile *objfile = module->GetObjectFile(); 263 if (objfile) 264 { 265 const uint64_t sect_file_offset = objfile->GetOffset() + section->GetFileOffset(); 266 const uint64_t file_offset = sect_file_offset + offset; 267 uint64_t file_size = size; 268 if (file_size == UINT64_MAX) 269 { 270 file_size = section->GetByteSize(); 271 if (file_size > offset) 272 file_size -= offset; 273 else 274 file_size = 0; 275 } 276 DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size)); 277 if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) 278 { 279 DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp, 280 objfile->GetByteOrder(), 281 objfile->GetAddressByteSize())); 282 283 sb_data.SetOpaque (data_extractor_sp); 284 } 285 } 286 } 287 } 288 } 289 } 290 return sb_data; 291 } 292 293 SectionType 294 SBSection::GetSectionType () 295 { 296 if (m_opaque_ap.get()) 297 { 298 const Section *section = m_opaque_ap->GetSection(); 299 if (section) 300 return section->GetType(); 301 } 302 return eSectionTypeInvalid; 303 } 304 305 306 bool 307 SBSection::operator == (const SBSection &rhs) 308 { 309 SectionImpl *lhs_ptr = m_opaque_ap.get(); 310 SectionImpl *rhs_ptr = rhs.m_opaque_ap.get(); 311 if (lhs_ptr && rhs_ptr) 312 return lhs_ptr->GetSection() == rhs_ptr->GetSection(); 313 return false; 314 } 315 316 bool 317 SBSection::operator != (const SBSection &rhs) 318 { 319 SectionImpl *lhs_ptr = m_opaque_ap.get(); 320 SectionImpl *rhs_ptr = rhs.m_opaque_ap.get(); 321 if (lhs_ptr && rhs_ptr) 322 return lhs_ptr->GetSection() != rhs_ptr->GetSection(); 323 return false; 324 } 325 326 bool 327 SBSection::GetDescription (SBStream &description) 328 { 329 if (IsValid()) 330 { 331 const Section *section = m_opaque_ap->GetSection(); 332 const addr_t file_addr = section->GetFileAddress(); 333 description.Printf ("[0x%16.16llx-0x%16.16llx) ", file_addr, file_addr + section->GetByteSize()); 334 section->DumpName(description.get()); 335 } 336 else 337 { 338 description.Printf ("No value"); 339 } 340 341 return true; 342 } 343 344