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