Home | History | Annotate | Download | only in ELF
      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 #include "lldb/Core/Section.h"
     14 #include "lldb/Core/Stream.h"
     15 
     16 #include "ELFHeader.h"
     17 
     18 using namespace elf;
     19 using namespace lldb;
     20 using namespace llvm::ELF;
     21 
     22 //------------------------------------------------------------------------------
     23 // Static utility functions.
     24 //
     25 // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
     26 // with error handling code and provide for parsing a sequence of values.
     27 static bool
     28 GetMaxU64(const lldb_private::DataExtractor &data,
     29           lldb::offset_t *offset,
     30           uint64_t *value,
     31           uint32_t byte_size)
     32 {
     33     const lldb::offset_t saved_offset = *offset;
     34     *value = data.GetMaxU64(offset, byte_size);
     35     return *offset != saved_offset;
     36 }
     37 
     38 static bool
     39 GetMaxU64(const lldb_private::DataExtractor &data,
     40           lldb::offset_t *offset,
     41           uint64_t *value,
     42           uint32_t byte_size,
     43           uint32_t count)
     44 {
     45     lldb::offset_t saved_offset = *offset;
     46 
     47     for (uint32_t i = 0; i < count; ++i, ++value)
     48     {
     49         if (GetMaxU64(data, offset, value, byte_size) == false)
     50         {
     51             *offset = saved_offset;
     52             return false;
     53         }
     54     }
     55     return true;
     56 }
     57 
     58 static bool
     59 GetMaxS64(const lldb_private::DataExtractor &data,
     60           lldb::offset_t *offset,
     61           int64_t *value,
     62           uint32_t byte_size)
     63 {
     64     const lldb::offset_t saved_offset = *offset;
     65     *value = data.GetMaxS64(offset, byte_size);
     66     return *offset != saved_offset;
     67 }
     68 
     69 static bool
     70 GetMaxS64(const lldb_private::DataExtractor &data,
     71           lldb::offset_t *offset,
     72           int64_t *value,
     73           uint32_t byte_size,
     74           uint32_t count)
     75 {
     76     lldb::offset_t saved_offset = *offset;
     77 
     78     for (uint32_t i = 0; i < count; ++i, ++value)
     79     {
     80         if (GetMaxS64(data, offset, value, byte_size) == false)
     81         {
     82             *offset = saved_offset;
     83             return false;
     84         }
     85     }
     86     return true;
     87 }
     88 
     89 //------------------------------------------------------------------------------
     90 // ELFHeader
     91 
     92 ELFHeader::ELFHeader()
     93 {
     94     memset(this, 0, sizeof(ELFHeader));
     95 }
     96 
     97 ByteOrder
     98 ELFHeader::GetByteOrder() const
     99 {
    100     if (e_ident[EI_DATA] == ELFDATA2MSB)
    101         return eByteOrderBig;
    102     if (e_ident[EI_DATA] == ELFDATA2LSB)
    103         return eByteOrderLittle;
    104     return eByteOrderInvalid;
    105 }
    106 
    107 bool
    108 ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset)
    109 {
    110     // Read e_ident.  This provides byte order and address size info.
    111     if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
    112         return false;
    113 
    114     const unsigned byte_size = Is32Bit() ? 4 : 8;
    115     data.SetByteOrder(GetByteOrder());
    116     data.SetAddressByteSize(byte_size);
    117 
    118     // Read e_type and e_machine.
    119     if (data.GetU16(offset, &e_type, 2) == NULL)
    120         return false;
    121 
    122     // Read e_version.
    123     if (data.GetU32(offset, &e_version, 1) == NULL)
    124         return false;
    125 
    126     // Read e_entry, e_phoff and e_shoff.
    127     if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
    128         return false;
    129 
    130     // Read e_flags.
    131     if (data.GetU32(offset, &e_flags, 1) == NULL)
    132         return false;
    133 
    134     // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and
    135     // e_shstrndx.
    136     if (data.GetU16(offset, &e_ehsize, 6) == NULL)
    137         return false;
    138 
    139     return true;
    140 }
    141 
    142 bool
    143 ELFHeader::MagicBytesMatch(const uint8_t *magic)
    144 {
    145     return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;
    146 }
    147 
    148 unsigned
    149 ELFHeader::AddressSizeInBytes(const uint8_t *magic)
    150 {
    151     unsigned address_size = 0;
    152 
    153     switch (magic[EI_CLASS])
    154     {
    155     case ELFCLASS32:
    156         address_size = 4;
    157         break;
    158 
    159     case ELFCLASS64:
    160         address_size = 8;
    161         break;
    162     }
    163     return address_size;
    164 }
    165 
    166 unsigned
    167 ELFHeader::GetRelocationJumpSlotType() const
    168 {
    169     unsigned slot = 0;
    170 
    171     switch (e_machine)
    172     {
    173     default:
    174         assert(false && "architecture not supported");
    175         break;
    176     case EM_386:
    177     case EM_486:
    178         slot = R_386_JUMP_SLOT;
    179         break;
    180     case EM_X86_64:
    181         slot = R_X86_64_JUMP_SLOT;
    182         break;
    183     case EM_ARM:
    184         slot = R_ARM_JUMP_SLOT;
    185         break;
    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 #define ENUM_TO_CSTR(e) case e: return #e
    237 
    238 const char *
    239 ELFSymbol::bindingToCString(unsigned char binding)
    240 {
    241     switch (binding)
    242     {
    243     ENUM_TO_CSTR(STB_LOCAL);
    244     ENUM_TO_CSTR(STB_GLOBAL);
    245     ENUM_TO_CSTR(STB_WEAK);
    246     ENUM_TO_CSTR(STB_LOOS);
    247     ENUM_TO_CSTR(STB_HIOS);
    248     ENUM_TO_CSTR(STB_LOPROC);
    249     ENUM_TO_CSTR(STB_HIPROC);
    250     }
    251     return "";
    252 }
    253 
    254 const char *
    255 ELFSymbol::typeToCString(unsigned char type)
    256 {
    257     switch (type)
    258     {
    259     ENUM_TO_CSTR(STT_NOTYPE);
    260     ENUM_TO_CSTR(STT_OBJECT);
    261     ENUM_TO_CSTR(STT_FUNC);
    262     ENUM_TO_CSTR(STT_SECTION);
    263     ENUM_TO_CSTR(STT_FILE);
    264     ENUM_TO_CSTR(STT_COMMON);
    265     ENUM_TO_CSTR(STT_TLS);
    266     ENUM_TO_CSTR(STT_LOOS);
    267     ENUM_TO_CSTR(STT_HIOS);
    268     ENUM_TO_CSTR(STT_GNU_IFUNC);
    269     ENUM_TO_CSTR(STT_LOPROC);
    270     ENUM_TO_CSTR(STT_HIPROC);
    271     }
    272     return "";
    273 }
    274 
    275 const char *
    276 ELFSymbol::sectionIndexToCString (elf_half shndx,
    277                                   const lldb_private::SectionList *section_list)
    278 {
    279     switch (shndx)
    280     {
    281     ENUM_TO_CSTR(SHN_UNDEF);
    282     ENUM_TO_CSTR(SHN_LOPROC);
    283     ENUM_TO_CSTR(SHN_HIPROC);
    284     ENUM_TO_CSTR(SHN_LOOS);
    285     ENUM_TO_CSTR(SHN_HIOS);
    286     ENUM_TO_CSTR(SHN_ABS);
    287     ENUM_TO_CSTR(SHN_COMMON);
    288     ENUM_TO_CSTR(SHN_XINDEX);
    289     default:
    290         {
    291             const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get();
    292             if (section)
    293                 return section->GetName().AsCString("");
    294         }
    295         break;
    296     }
    297     return "";
    298 }
    299 
    300 void
    301 ELFSymbol::Dump (lldb_private::Stream *s,
    302                  uint32_t idx,
    303                  const lldb_private::DataExtractor *strtab_data,
    304                  const lldb_private::SectionList *section_list)
    305 {
    306     s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n",
    307               idx,
    308               st_value,
    309               st_size,
    310               st_name,
    311               st_info,
    312               bindingToCString (getBinding()),
    313               typeToCString (getType()),
    314               st_other,
    315               st_shndx,
    316               sectionIndexToCString (st_shndx, section_list),
    317               strtab_data ? strtab_data->PeekCStr(st_name) : "");
    318 }
    319 
    320 bool
    321 ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
    322 {
    323     const unsigned byte_size = data.GetAddressByteSize();
    324     const bool parsing_32 = byte_size == 4;
    325 
    326     // Read st_name.
    327     if (data.GetU32(offset, &st_name, 1) == NULL)
    328         return false;
    329 
    330     if (parsing_32)
    331     {
    332         // Read st_value and st_size.
    333         if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
    334             return false;
    335 
    336         // Read st_info and st_other.
    337         if (data.GetU8(offset, &st_info, 2) == NULL)
    338             return false;
    339 
    340         // Read st_shndx.
    341         if (data.GetU16(offset, &st_shndx, 1) == NULL)
    342             return false;
    343     }
    344     else
    345     {
    346         // Read st_info and st_other.
    347         if (data.GetU8(offset, &st_info, 2) == NULL)
    348             return false;
    349 
    350         // Read st_shndx.
    351         if (data.GetU16(offset, &st_shndx, 1) == NULL)
    352             return false;
    353 
    354         // Read st_value and st_size.
    355         if (data.GetU64(offset, &st_value, 2) == NULL)
    356             return false;
    357     }
    358     return true;
    359 }
    360 
    361 //------------------------------------------------------------------------------
    362 // ELFProgramHeader
    363 
    364 ELFProgramHeader::ELFProgramHeader()
    365 {
    366     memset(this, 0, sizeof(ELFProgramHeader));
    367 }
    368 
    369 bool
    370 ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
    371                         lldb::offset_t *offset)
    372 {
    373     const uint32_t byte_size = data.GetAddressByteSize();
    374     const bool parsing_32 = byte_size == 4;
    375 
    376     // Read p_type;
    377     if (data.GetU32(offset, &p_type, 1) == NULL)
    378         return false;
    379 
    380     if (parsing_32) {
    381         // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
    382         if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
    383             return false;
    384 
    385         // Read p_flags.
    386         if (data.GetU32(offset, &p_flags, 1) == NULL)
    387             return false;
    388 
    389         // Read p_align.
    390         if (GetMaxU64(data, offset, &p_align, byte_size) == false)
    391             return false;
    392     }
    393     else {
    394         // Read p_flags.
    395         if (data.GetU32(offset, &p_flags, 1) == NULL)
    396             return false;
    397 
    398         // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
    399         if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
    400             return false;
    401     }
    402 
    403     return true;
    404 }
    405 
    406 //------------------------------------------------------------------------------
    407 // ELFDynamic
    408 
    409 ELFDynamic::ELFDynamic()
    410 {
    411     memset(this, 0, sizeof(ELFDynamic));
    412 }
    413 
    414 bool
    415 ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
    416 {
    417     const unsigned byte_size = data.GetAddressByteSize();
    418     return GetMaxS64(data, offset, &d_tag, byte_size, 2);
    419 }
    420 
    421 //------------------------------------------------------------------------------
    422 // ELFRel
    423 
    424 ELFRel::ELFRel()
    425 {
    426     memset(this, 0, sizeof(ELFRel));
    427 }
    428 
    429 bool
    430 ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
    431 {
    432     const unsigned byte_size = data.GetAddressByteSize();
    433 
    434     // Read r_offset and r_info.
    435     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
    436         return false;
    437 
    438     return true;
    439 }
    440 
    441 //------------------------------------------------------------------------------
    442 // ELFRela
    443 
    444 ELFRela::ELFRela()
    445 {
    446     memset(this, 0, sizeof(ELFRela));
    447 }
    448 
    449 bool
    450 ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
    451 {
    452     const unsigned byte_size = data.GetAddressByteSize();
    453 
    454     // Read r_offset and r_info.
    455     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
    456         return false;
    457 
    458     // Read r_addend;
    459     if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
    460         return false;
    461 
    462     return true;
    463 }
    464 
    465 
    466