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