1 //===-- SBSection.cpp -----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBSection.h" 10 #include "SBReproducerPrivate.h" 11 #include "lldb/API/SBStream.h" 12 #include "lldb/API/SBTarget.h" 13 #include "lldb/Core/Module.h" 14 #include "lldb/Core/Section.h" 15 #include "lldb/Symbol/ObjectFile.h" 16 #include "lldb/Utility/DataBuffer.h" 17 #include "lldb/Utility/DataExtractor.h" 18 #include "lldb/Utility/StreamString.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 23 SBSection::SBSection() : m_opaque_wp() { 24 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSection); 25 } 26 27 SBSection::SBSection(const SBSection &rhs) : m_opaque_wp(rhs.m_opaque_wp) { 28 LLDB_RECORD_CONSTRUCTOR(SBSection, (const lldb::SBSection &), rhs); 29 } 30 31 SBSection::SBSection(const lldb::SectionSP §ion_sp) 32 : m_opaque_wp() // Don't init with section_sp otherwise this will throw if 33 // section_sp doesn't contain a valid Section * 34 { 35 if (section_sp) 36 m_opaque_wp = section_sp; 37 } 38 39 const SBSection &SBSection::operator=(const SBSection &rhs) { 40 LLDB_RECORD_METHOD(const lldb::SBSection &, 41 SBSection, operator=,(const lldb::SBSection &), rhs); 42 43 m_opaque_wp = rhs.m_opaque_wp; 44 return LLDB_RECORD_RESULT(*this); 45 } 46 47 SBSection::~SBSection() = default; 48 49 bool SBSection::IsValid() const { 50 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSection, IsValid); 51 return this->operator bool(); 52 } 53 SBSection::operator bool() const { 54 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSection, operator bool); 55 56 SectionSP section_sp(GetSP()); 57 return section_sp && section_sp->GetModule().get() != nullptr; 58 } 59 60 const char *SBSection::GetName() { 61 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBSection, GetName); 62 63 SectionSP section_sp(GetSP()); 64 if (section_sp) 65 return section_sp->GetName().GetCString(); 66 return nullptr; 67 } 68 69 lldb::SBSection SBSection::GetParent() { 70 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSection, SBSection, GetParent); 71 72 lldb::SBSection sb_section; 73 SectionSP section_sp(GetSP()); 74 if (section_sp) { 75 SectionSP parent_section_sp(section_sp->GetParent()); 76 if (parent_section_sp) 77 sb_section.SetSP(parent_section_sp); 78 } 79 return LLDB_RECORD_RESULT(sb_section); 80 } 81 82 lldb::SBSection SBSection::FindSubSection(const char *sect_name) { 83 LLDB_RECORD_METHOD(lldb::SBSection, SBSection, FindSubSection, (const char *), 84 sect_name); 85 86 lldb::SBSection sb_section; 87 if (sect_name) { 88 SectionSP section_sp(GetSP()); 89 if (section_sp) { 90 ConstString const_sect_name(sect_name); 91 sb_section.SetSP( 92 section_sp->GetChildren().FindSectionByName(const_sect_name)); 93 } 94 } 95 return LLDB_RECORD_RESULT(sb_section); 96 } 97 98 size_t SBSection::GetNumSubSections() { 99 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBSection, GetNumSubSections); 100 101 SectionSP section_sp(GetSP()); 102 if (section_sp) 103 return section_sp->GetChildren().GetSize(); 104 return 0; 105 } 106 107 lldb::SBSection SBSection::GetSubSectionAtIndex(size_t idx) { 108 LLDB_RECORD_METHOD(lldb::SBSection, SBSection, GetSubSectionAtIndex, (size_t), 109 idx); 110 111 lldb::SBSection sb_section; 112 SectionSP section_sp(GetSP()); 113 if (section_sp) 114 sb_section.SetSP(section_sp->GetChildren().GetSectionAtIndex(idx)); 115 return LLDB_RECORD_RESULT(sb_section); 116 } 117 118 lldb::SectionSP SBSection::GetSP() const { return m_opaque_wp.lock(); } 119 120 void SBSection::SetSP(const lldb::SectionSP §ion_sp) { 121 m_opaque_wp = section_sp; 122 } 123 124 lldb::addr_t SBSection::GetFileAddress() { 125 LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBSection, GetFileAddress); 126 127 lldb::addr_t file_addr = LLDB_INVALID_ADDRESS; 128 SectionSP section_sp(GetSP()); 129 if (section_sp) 130 return section_sp->GetFileAddress(); 131 return file_addr; 132 } 133 134 lldb::addr_t SBSection::GetLoadAddress(lldb::SBTarget &sb_target) { 135 LLDB_RECORD_METHOD(lldb::addr_t, SBSection, GetLoadAddress, 136 (lldb::SBTarget &), sb_target); 137 138 TargetSP target_sp(sb_target.GetSP()); 139 if (target_sp) { 140 SectionSP section_sp(GetSP()); 141 if (section_sp) 142 return section_sp->GetLoadBaseAddress(target_sp.get()); 143 } 144 return LLDB_INVALID_ADDRESS; 145 } 146 147 lldb::addr_t SBSection::GetByteSize() { 148 LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBSection, GetByteSize); 149 150 SectionSP section_sp(GetSP()); 151 if (section_sp) 152 return section_sp->GetByteSize(); 153 return 0; 154 } 155 156 uint64_t SBSection::GetFileOffset() { 157 LLDB_RECORD_METHOD_NO_ARGS(uint64_t, SBSection, GetFileOffset); 158 159 SectionSP section_sp(GetSP()); 160 if (section_sp) { 161 ModuleSP module_sp(section_sp->GetModule()); 162 if (module_sp) { 163 ObjectFile *objfile = module_sp->GetObjectFile(); 164 if (objfile) 165 return objfile->GetFileOffset() + section_sp->GetFileOffset(); 166 } 167 } 168 return UINT64_MAX; 169 } 170 171 uint64_t SBSection::GetFileByteSize() { 172 LLDB_RECORD_METHOD_NO_ARGS(uint64_t, SBSection, GetFileByteSize); 173 174 SectionSP section_sp(GetSP()); 175 if (section_sp) 176 return section_sp->GetFileSize(); 177 return 0; 178 } 179 180 SBData SBSection::GetSectionData() { 181 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBData, SBSection, GetSectionData); 182 183 return LLDB_RECORD_RESULT(GetSectionData(0, UINT64_MAX)); 184 } 185 186 SBData SBSection::GetSectionData(uint64_t offset, uint64_t size) { 187 LLDB_RECORD_METHOD(lldb::SBData, SBSection, GetSectionData, 188 (uint64_t, uint64_t), offset, size); 189 190 SBData sb_data; 191 SectionSP section_sp(GetSP()); 192 if (section_sp) { 193 const uint64_t sect_file_size = section_sp->GetFileSize(); 194 if (sect_file_size > 0) { 195 ModuleSP module_sp(section_sp->GetModule()); 196 if (module_sp) { 197 ObjectFile *objfile = module_sp->GetObjectFile(); 198 if (objfile) { 199 const uint64_t sect_file_offset = 200 objfile->GetFileOffset() + section_sp->GetFileOffset(); 201 const uint64_t file_offset = sect_file_offset + offset; 202 uint64_t file_size = size; 203 if (file_size == UINT64_MAX) { 204 file_size = section_sp->GetByteSize(); 205 if (file_size > offset) 206 file_size -= offset; 207 else 208 file_size = 0; 209 } 210 auto data_buffer_sp = FileSystem::Instance().CreateDataBuffer( 211 objfile->GetFileSpec().GetPath(), file_size, file_offset); 212 if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) { 213 DataExtractorSP data_extractor_sp( 214 new DataExtractor(data_buffer_sp, objfile->GetByteOrder(), 215 objfile->GetAddressByteSize())); 216 217 sb_data.SetOpaque(data_extractor_sp); 218 } 219 } 220 } 221 } 222 } 223 return LLDB_RECORD_RESULT(sb_data); 224 } 225 226 SectionType SBSection::GetSectionType() { 227 LLDB_RECORD_METHOD_NO_ARGS(lldb::SectionType, SBSection, GetSectionType); 228 229 SectionSP section_sp(GetSP()); 230 if (section_sp.get()) 231 return section_sp->GetType(); 232 return eSectionTypeInvalid; 233 } 234 235 uint32_t SBSection::GetPermissions() const { 236 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBSection, GetPermissions); 237 238 SectionSP section_sp(GetSP()); 239 if (section_sp) 240 return section_sp->GetPermissions(); 241 return 0; 242 } 243 244 uint32_t SBSection::GetTargetByteSize() { 245 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBSection, GetTargetByteSize); 246 247 SectionSP section_sp(GetSP()); 248 if (section_sp.get()) 249 return section_sp->GetTargetByteSize(); 250 return 0; 251 } 252 253 bool SBSection::operator==(const SBSection &rhs) { 254 LLDB_RECORD_METHOD(bool, SBSection, operator==,(const lldb::SBSection &), 255 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 264 bool SBSection::operator!=(const SBSection &rhs) { 265 LLDB_RECORD_METHOD(bool, SBSection, operator!=,(const lldb::SBSection &), 266 rhs); 267 268 SectionSP lhs_section_sp(GetSP()); 269 SectionSP rhs_section_sp(rhs.GetSP()); 270 return lhs_section_sp != rhs_section_sp; 271 } 272 273 bool SBSection::GetDescription(SBStream &description) { 274 LLDB_RECORD_METHOD(bool, SBSection, GetDescription, (lldb::SBStream &), 275 description); 276 277 Stream &strm = description.ref(); 278 279 SectionSP section_sp(GetSP()); 280 if (section_sp) { 281 const addr_t file_addr = section_sp->GetFileAddress(); 282 strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr, 283 file_addr + section_sp->GetByteSize()); 284 section_sp->DumpName(strm.AsRawOstream()); 285 } else { 286 strm.PutCString("No value"); 287 } 288 289 return true; 290 } 291 292 namespace lldb_private { 293 namespace repro { 294 295 template <> 296 void RegisterMethods<SBSection>(Registry &R) { 297 LLDB_REGISTER_CONSTRUCTOR(SBSection, ()); 298 LLDB_REGISTER_CONSTRUCTOR(SBSection, (const lldb::SBSection &)); 299 LLDB_REGISTER_METHOD(const lldb::SBSection &, 300 SBSection, operator=,(const lldb::SBSection &)); 301 LLDB_REGISTER_METHOD_CONST(bool, SBSection, IsValid, ()); 302 LLDB_REGISTER_METHOD_CONST(bool, SBSection, operator bool, ()); 303 LLDB_REGISTER_METHOD(const char *, SBSection, GetName, ()); 304 LLDB_REGISTER_METHOD(lldb::SBSection, SBSection, GetParent, ()); 305 LLDB_REGISTER_METHOD(lldb::SBSection, SBSection, FindSubSection, 306 (const char *)); 307 LLDB_REGISTER_METHOD(size_t, SBSection, GetNumSubSections, ()); 308 LLDB_REGISTER_METHOD(lldb::SBSection, SBSection, GetSubSectionAtIndex, 309 (size_t)); 310 LLDB_REGISTER_METHOD(lldb::addr_t, SBSection, GetFileAddress, ()); 311 LLDB_REGISTER_METHOD(lldb::addr_t, SBSection, GetLoadAddress, 312 (lldb::SBTarget &)); 313 LLDB_REGISTER_METHOD(lldb::addr_t, SBSection, GetByteSize, ()); 314 LLDB_REGISTER_METHOD(uint64_t, SBSection, GetFileOffset, ()); 315 LLDB_REGISTER_METHOD(uint64_t, SBSection, GetFileByteSize, ()); 316 LLDB_REGISTER_METHOD(lldb::SBData, SBSection, GetSectionData, ()); 317 LLDB_REGISTER_METHOD(lldb::SBData, SBSection, GetSectionData, 318 (uint64_t, uint64_t)); 319 LLDB_REGISTER_METHOD(lldb::SectionType, SBSection, GetSectionType, ()); 320 LLDB_REGISTER_METHOD_CONST(uint32_t, SBSection, GetPermissions, ()); 321 LLDB_REGISTER_METHOD(uint32_t, SBSection, GetTargetByteSize, ()); 322 LLDB_REGISTER_METHOD(bool, SBSection, operator==,(const lldb::SBSection &)); 323 LLDB_REGISTER_METHOD(bool, SBSection, operator!=,(const lldb::SBSection &)); 324 LLDB_REGISTER_METHOD(bool, SBSection, GetDescription, (lldb::SBStream &)); 325 } 326 327 } 328 } 329