1 //===-- ELFHeader.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 <cstring> 11 12 #include "lldb/Core/DataExtractor.h" 13 14 #include "ELFHeader.h" 15 16 using namespace elf; 17 using namespace lldb; 18 using namespace llvm::ELF; 19 20 //------------------------------------------------------------------------------ 21 // Static utility functions. 22 // 23 // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor 24 // with error handling code and provide for parsing a sequence of values. 25 static bool 26 GetMaxU64(const lldb_private::DataExtractor &data, 27 lldb::offset_t *offset, 28 uint64_t *value, 29 uint32_t byte_size) 30 { 31 const lldb::offset_t saved_offset = *offset; 32 *value = data.GetMaxU64(offset, byte_size); 33 return *offset != saved_offset; 34 } 35 36 static bool 37 GetMaxU64(const lldb_private::DataExtractor &data, 38 lldb::offset_t *offset, 39 uint64_t *value, 40 uint32_t byte_size, 41 uint32_t count) 42 { 43 lldb::offset_t saved_offset = *offset; 44 45 for (uint32_t i = 0; i < count; ++i, ++value) 46 { 47 if (GetMaxU64(data, offset, value, byte_size) == false) 48 { 49 *offset = saved_offset; 50 return false; 51 } 52 } 53 return true; 54 } 55 56 static bool 57 GetMaxS64(const lldb_private::DataExtractor &data, 58 lldb::offset_t *offset, 59 int64_t *value, 60 uint32_t byte_size) 61 { 62 const lldb::offset_t saved_offset = *offset; 63 *value = data.GetMaxS64(offset, byte_size); 64 return *offset != saved_offset; 65 } 66 67 static bool 68 GetMaxS64(const lldb_private::DataExtractor &data, 69 lldb::offset_t *offset, 70 int64_t *value, 71 uint32_t byte_size, 72 uint32_t count) 73 { 74 lldb::offset_t saved_offset = *offset; 75 76 for (uint32_t i = 0; i < count; ++i, ++value) 77 { 78 if (GetMaxS64(data, offset, value, byte_size) == false) 79 { 80 *offset = saved_offset; 81 return false; 82 } 83 } 84 return true; 85 } 86 87 //------------------------------------------------------------------------------ 88 // ELFHeader 89 90 ELFHeader::ELFHeader() 91 { 92 memset(this, 0, sizeof(ELFHeader)); 93 } 94 95 ByteOrder 96 ELFHeader::GetByteOrder() const 97 { 98 if (e_ident[EI_DATA] == ELFDATA2MSB) 99 return eByteOrderBig; 100 if (e_ident[EI_DATA] == ELFDATA2LSB) 101 return eByteOrderLittle; 102 return eByteOrderInvalid; 103 } 104 105 bool 106 ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset) 107 { 108 // Read e_ident. This provides byte order and address size info. 109 if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) 110 return false; 111 112 const unsigned byte_size = Is32Bit() ? 4 : 8; 113 data.SetByteOrder(GetByteOrder()); 114 data.SetAddressByteSize(byte_size); 115 116 // Read e_type and e_machine. 117 if (data.GetU16(offset, &e_type, 2) == NULL) 118 return false; 119 120 // Read e_version. 121 if (data.GetU32(offset, &e_version, 1) == NULL) 122 return false; 123 124 // Read e_entry, e_phoff and e_shoff. 125 if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false) 126 return false; 127 128 // Read e_flags. 129 if (data.GetU32(offset, &e_flags, 1) == NULL) 130 return false; 131 132 // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and 133 // e_shstrndx. 134 if (data.GetU16(offset, &e_ehsize, 6) == NULL) 135 return false; 136 137 return true; 138 } 139 140 bool 141 ELFHeader::MagicBytesMatch(const uint8_t *magic) 142 { 143 return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0; 144 } 145 146 unsigned 147 ELFHeader::AddressSizeInBytes(const uint8_t *magic) 148 { 149 unsigned address_size = 0; 150 151 switch (magic[EI_CLASS]) 152 { 153 case ELFCLASS32: 154 address_size = 4; 155 break; 156 157 case ELFCLASS64: 158 address_size = 8; 159 break; 160 } 161 return address_size; 162 } 163 164 unsigned 165 ELFHeader::GetRelocationJumpSlotType() const 166 { 167 unsigned slot = 0; 168 169 switch (e_machine) 170 { 171 default: 172 assert(false && "architecture not supported"); 173 break; 174 case EM_386: 175 case EM_486: 176 slot = R_386_JUMP_SLOT; 177 break; 178 case EM_X86_64: 179 slot = R_X86_64_JUMP_SLOT; 180 break; 181 case EM_ARM: 182 slot = R_ARM_JUMP_SLOT; 183 break; 184 case EM_MBLAZE: 185 slot = R_MICROBLAZE_JUMP_SLOT; 186 } 187 188 return slot; 189 } 190 191 //------------------------------------------------------------------------------ 192 // ELFSectionHeader 193 194 ELFSectionHeader::ELFSectionHeader() 195 { 196 memset(this, 0, sizeof(ELFSectionHeader)); 197 } 198 199 bool 200 ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, 201 lldb::offset_t *offset) 202 { 203 const unsigned byte_size = data.GetAddressByteSize(); 204 205 // Read sh_name and sh_type. 206 if (data.GetU32(offset, &sh_name, 2) == NULL) 207 return false; 208 209 // Read sh_flags. 210 if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) 211 return false; 212 213 // Read sh_addr, sh_off and sh_size. 214 if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) 215 return false; 216 217 // Read sh_link and sh_info. 218 if (data.GetU32(offset, &sh_link, 2) == NULL) 219 return false; 220 221 // Read sh_addralign and sh_entsize. 222 if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) 223 return false; 224 225 return true; 226 } 227 228 //------------------------------------------------------------------------------ 229 // ELFSymbol 230 231 ELFSymbol::ELFSymbol() 232 { 233 memset(this, 0, sizeof(ELFSymbol)); 234 } 235 236 bool 237 ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 238 { 239 const unsigned byte_size = data.GetAddressByteSize(); 240 const bool parsing_32 = byte_size == 4; 241 242 // Read st_name. 243 if (data.GetU32(offset, &st_name, 1) == NULL) 244 return false; 245 246 if (parsing_32) 247 { 248 // Read st_value and st_size. 249 if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) 250 return false; 251 252 // Read st_info and st_other. 253 if (data.GetU8(offset, &st_info, 2) == NULL) 254 return false; 255 256 // Read st_shndx. 257 if (data.GetU16(offset, &st_shndx, 1) == NULL) 258 return false; 259 } 260 else 261 { 262 // Read st_info and st_other. 263 if (data.GetU8(offset, &st_info, 2) == NULL) 264 return false; 265 266 // Read st_shndx. 267 if (data.GetU16(offset, &st_shndx, 1) == NULL) 268 return false; 269 270 // Read st_value and st_size. 271 if (data.GetU64(offset, &st_value, 2) == NULL) 272 return false; 273 } 274 return true; 275 } 276 277 //------------------------------------------------------------------------------ 278 // ELFProgramHeader 279 280 ELFProgramHeader::ELFProgramHeader() 281 { 282 memset(this, 0, sizeof(ELFProgramHeader)); 283 } 284 285 bool 286 ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, 287 lldb::offset_t *offset) 288 { 289 const uint32_t byte_size = data.GetAddressByteSize(); 290 const bool parsing_32 = byte_size == 4; 291 292 // Read p_type; 293 if (data.GetU32(offset, &p_type, 1) == NULL) 294 return false; 295 296 if (parsing_32) { 297 // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. 298 if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) 299 return false; 300 301 // Read p_flags. 302 if (data.GetU32(offset, &p_flags, 1) == NULL) 303 return false; 304 305 // Read p_align. 306 if (GetMaxU64(data, offset, &p_align, byte_size) == false) 307 return false; 308 } 309 else { 310 // Read p_flags. 311 if (data.GetU32(offset, &p_flags, 1) == NULL) 312 return false; 313 314 // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. 315 if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) 316 return false; 317 } 318 319 return true; 320 } 321 322 //------------------------------------------------------------------------------ 323 // ELFDynamic 324 325 ELFDynamic::ELFDynamic() 326 { 327 memset(this, 0, sizeof(ELFDynamic)); 328 } 329 330 bool 331 ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 332 { 333 const unsigned byte_size = data.GetAddressByteSize(); 334 return GetMaxS64(data, offset, &d_tag, byte_size, 2); 335 } 336 337 //------------------------------------------------------------------------------ 338 // ELFRel 339 340 ELFRel::ELFRel() 341 { 342 memset(this, 0, sizeof(ELFRel)); 343 } 344 345 bool 346 ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 347 { 348 const unsigned byte_size = data.GetAddressByteSize(); 349 350 // Read r_offset and r_info. 351 if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) 352 return false; 353 354 return true; 355 } 356 357 //------------------------------------------------------------------------------ 358 // ELFRela 359 360 ELFRela::ELFRela() 361 { 362 memset(this, 0, sizeof(ELFRela)); 363 } 364 365 bool 366 ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 367 { 368 const unsigned byte_size = data.GetAddressByteSize(); 369 370 // Read r_offset and r_info. 371 if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) 372 return false; 373 374 // Read r_addend; 375 if (GetMaxS64(data, offset, &r_addend, byte_size) == false) 376 return false; 377 378 return true; 379 } 380 381 382