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 uint32_t *offset, uint64_t *value, uint32_t byte_size) 28 { 29 const uint32_t saved_offset = *offset; 30 *value = data.GetMaxU64(offset, byte_size); 31 return *offset != saved_offset; 32 } 33 34 static bool 35 GetMaxU64(const lldb_private::DataExtractor &data, 36 uint32_t *offset, uint64_t *value, uint32_t byte_size, 37 uint32_t count) 38 { 39 uint32_t saved_offset = *offset; 40 41 for (uint32_t i = 0; i < count; ++i, ++value) 42 { 43 if (GetMaxU64(data, offset, value, byte_size) == false) 44 { 45 *offset = saved_offset; 46 return false; 47 } 48 } 49 return true; 50 } 51 52 static bool 53 GetMaxS64(const lldb_private::DataExtractor &data, 54 uint32_t *offset, int64_t *value, uint32_t byte_size) 55 { 56 const uint32_t saved_offset = *offset; 57 *value = data.GetMaxS64(offset, byte_size); 58 return *offset != saved_offset; 59 } 60 61 static bool 62 GetMaxS64(const lldb_private::DataExtractor &data, 63 uint32_t *offset, int64_t *value, uint32_t byte_size, 64 uint32_t count) 65 { 66 uint32_t saved_offset = *offset; 67 68 for (uint32_t i = 0; i < count; ++i, ++value) 69 { 70 if (GetMaxS64(data, offset, value, byte_size) == false) 71 { 72 *offset = saved_offset; 73 return false; 74 } 75 } 76 return true; 77 } 78 79 //------------------------------------------------------------------------------ 80 // ELFHeader 81 82 ELFHeader::ELFHeader() 83 { 84 memset(this, 0, sizeof(ELFHeader)); 85 } 86 87 ByteOrder 88 ELFHeader::GetByteOrder() const 89 { 90 if (e_ident[EI_DATA] == ELFDATA2MSB) 91 return eByteOrderBig; 92 if (e_ident[EI_DATA] == ELFDATA2LSB) 93 return eByteOrderLittle; 94 return eByteOrderInvalid; 95 } 96 97 bool 98 ELFHeader::Parse(lldb_private::DataExtractor &data, uint32_t *offset) 99 { 100 // Read e_ident. This provides byte order and address size info. 101 if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) 102 return false; 103 104 const unsigned byte_size = Is32Bit() ? 4 : 8; 105 data.SetByteOrder(GetByteOrder()); 106 data.SetAddressByteSize(byte_size); 107 108 // Read e_type and e_machine. 109 if (data.GetU16(offset, &e_type, 2) == NULL) 110 return false; 111 112 // Read e_version. 113 if (data.GetU32(offset, &e_version, 1) == NULL) 114 return false; 115 116 // Read e_entry, e_phoff and e_shoff. 117 if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false) 118 return false; 119 120 // Read e_flags. 121 if (data.GetU32(offset, &e_flags, 1) == NULL) 122 return false; 123 124 // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and 125 // e_shstrndx. 126 if (data.GetU16(offset, &e_ehsize, 6) == NULL) 127 return false; 128 129 return true; 130 } 131 132 bool 133 ELFHeader::MagicBytesMatch(const uint8_t *magic) 134 { 135 return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0; 136 } 137 138 unsigned 139 ELFHeader::AddressSizeInBytes(const uint8_t *magic) 140 { 141 unsigned address_size = 0; 142 143 switch (magic[EI_CLASS]) 144 { 145 case ELFCLASS32: 146 address_size = 4; 147 break; 148 149 case ELFCLASS64: 150 address_size = 8; 151 break; 152 } 153 return address_size; 154 } 155 156 //------------------------------------------------------------------------------ 157 // ELFSectionHeader 158 159 ELFSectionHeader::ELFSectionHeader() 160 { 161 memset(this, 0, sizeof(ELFSectionHeader)); 162 } 163 164 bool 165 ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, 166 uint32_t *offset) 167 { 168 const unsigned byte_size = data.GetAddressByteSize(); 169 170 // Read sh_name and sh_type. 171 if (data.GetU32(offset, &sh_name, 2) == NULL) 172 return false; 173 174 // Read sh_flags. 175 if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) 176 return false; 177 178 // Read sh_addr, sh_off and sh_size. 179 if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) 180 return false; 181 182 // Read sh_link and sh_info. 183 if (data.GetU32(offset, &sh_link, 2) == NULL) 184 return false; 185 186 // Read sh_addralign and sh_entsize. 187 if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) 188 return false; 189 190 return true; 191 } 192 193 //------------------------------------------------------------------------------ 194 // ELFSymbol 195 196 ELFSymbol::ELFSymbol() 197 { 198 memset(this, 0, sizeof(ELFSymbol)); 199 } 200 201 bool 202 ELFSymbol::Parse(const lldb_private::DataExtractor &data, uint32_t *offset) 203 { 204 const unsigned byte_size = data.GetAddressByteSize(); 205 const bool parsing_32 = byte_size == 4; 206 207 // Read st_name. 208 if (data.GetU32(offset, &st_name, 1) == NULL) 209 return false; 210 211 if (parsing_32) 212 { 213 // Read st_value and st_size. 214 if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) 215 return false; 216 217 // Read st_info and st_other. 218 if (data.GetU8(offset, &st_info, 2) == NULL) 219 return false; 220 221 // Read st_shndx. 222 if (data.GetU16(offset, &st_shndx, 1) == NULL) 223 return false; 224 } 225 else 226 { 227 // Read st_info and st_other. 228 if (data.GetU8(offset, &st_info, 2) == NULL) 229 return false; 230 231 // Read st_shndx. 232 if (data.GetU16(offset, &st_shndx, 1) == NULL) 233 return false; 234 235 // Read st_value and st_size. 236 if (data.GetU64(offset, &st_value, 2) == NULL) 237 return false; 238 } 239 return true; 240 } 241 242 //------------------------------------------------------------------------------ 243 // ELFProgramHeader 244 245 ELFProgramHeader::ELFProgramHeader() 246 { 247 memset(this, 0, sizeof(ELFProgramHeader)); 248 } 249 250 bool 251 ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, 252 uint32_t *offset) 253 { 254 const uint32_t byte_size = data.GetAddressByteSize(); 255 const bool parsing_32 = byte_size == 4; 256 257 // Read p_type; 258 if (data.GetU32(offset, &p_type, 1) == NULL) 259 return false; 260 261 if (parsing_32) { 262 // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. 263 if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) 264 return false; 265 266 // Read p_flags. 267 if (data.GetU32(offset, &p_flags, 1) == NULL) 268 return false; 269 270 // Read p_align. 271 if (GetMaxU64(data, offset, &p_align, byte_size) == false) 272 return false; 273 } 274 else { 275 // Read p_flags. 276 if (data.GetU32(offset, &p_flags, 1) == NULL) 277 return false; 278 279 // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. 280 if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) 281 return false; 282 } 283 284 return true; 285 } 286 287 //------------------------------------------------------------------------------ 288 // ELFDynamic 289 290 ELFDynamic::ELFDynamic() 291 { 292 memset(this, 0, sizeof(ELFDynamic)); 293 } 294 295 bool 296 ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset) 297 { 298 const unsigned byte_size = data.GetAddressByteSize(); 299 return GetMaxS64(data, offset, &d_tag, byte_size, 2); 300 } 301 302 303