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