79 } 80 81 if (m_next != NULL) { 82 delete m_next; 83 } 84 }; 85 86 87 //Check elf header to ensure the file is valid. 88 bool ElfFile::is_elf_file(Elf_Ehdr& hdr) { 89 return (ELFMAG0 == hdr.e_ident[EI_MAG0] && 90 ELFMAG1 == hdr.e_ident[EI_MAG1] && 91 ELFMAG2 == hdr.e_ident[EI_MAG2] && 92 ELFMAG3 == hdr.e_ident[EI_MAG3] && 93 ELFCLASSNONE != hdr.e_ident[EI_CLASS] && 94 ELFDATANONE != hdr.e_ident[EI_DATA]); 95 } 96 97 bool ElfFile::load_tables() { 98 assert(m_file, "file not open"); 99 assert(m_status == Decoder::no_error, "already in error"); 100 101 // read elf file header 102 if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) { 103 m_status = Decoder::file_invalid; 104 return false; 105 } 106 107 if (!is_elf_file(m_elfHdr)) { 108 m_status = Decoder::file_invalid; 109 return false; 110 } 111 112 // walk elf file's section headers, and load string tables 113 Elf_Shdr shdr; 114 if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) { 115 if (m_status != Decoder::no_error) return false; 116 117 for (int index = 0; index < m_elfHdr.e_shnum; index ++) { 118 if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { 119 m_status = Decoder::file_invalid; 120 return false; 121 } 122 // string table 123 if (shdr.sh_type == SHT_STRTAB) { 124 ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index); 125 if (table == NULL) { 126 m_status = Decoder::out_of_memory; 127 return false; 128 } 129 add_string_table(table); 130 } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { 131 ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); 132 if (table == NULL) { 133 m_status = Decoder::out_of_memory; 134 return false; 135 } 136 add_symbol_table(table); 137 } 138 } 139 } 140 return true; 141 } 142 143 const char* ElfFile::decode(address addr, int* offset) { 144 // something already went wrong, just give up 145 if (m_status != Decoder::no_error) { 146 return NULL; 147 } 148 149 ElfSymbolTable* symbol_table = m_symbol_tables; 150 int string_table_index; 151 int pos_in_string_table; 152 int off = INT_MAX; 153 bool found_symbol = false; 154 while (symbol_table != NULL) { 155 if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) { 156 found_symbol = true; 157 } 158 symbol_table = symbol_table->m_next; 159 } 160 if (!found_symbol) return NULL; 161 162 ElfStringTable* string_table = get_string_table(string_table_index); 163 if (string_table == NULL) { 164 m_status = Decoder::file_invalid; 165 return NULL; 166 } 167 if (offset) *offset = off; 168 return string_table->string_at(pos_in_string_table); 169 } 170 171 172 void ElfFile::add_symbol_table(ElfSymbolTable* table) { 173 if (m_symbol_tables == NULL) { 174 m_symbol_tables = table; 175 } else { 176 table->m_next = m_symbol_tables; 177 m_symbol_tables = table; 178 } 179 } 180 181 void ElfFile::add_string_table(ElfStringTable* table) { 182 if (m_string_tables == NULL) { 183 m_string_tables = table; 184 } else { 185 table->m_next = m_string_tables; 186 m_string_tables = table; 187 } 188 } | 79 } 80 81 if (m_next != NULL) { 82 delete m_next; 83 } 84 }; 85 86 87 //Check elf header to ensure the file is valid. 88 bool ElfFile::is_elf_file(Elf_Ehdr& hdr) { 89 return (ELFMAG0 == hdr.e_ident[EI_MAG0] && 90 ELFMAG1 == hdr.e_ident[EI_MAG1] && 91 ELFMAG2 == hdr.e_ident[EI_MAG2] && 92 ELFMAG3 == hdr.e_ident[EI_MAG3] && 93 ELFCLASSNONE != hdr.e_ident[EI_CLASS] && 94 ELFDATANONE != hdr.e_ident[EI_DATA]); 95 } 96 97 bool ElfFile::load_tables() { 98 assert(m_file, "file not open"); 99 assert(!Decoder::is_error(m_status), "already in error"); 100 101 // read elf file header 102 if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) { 103 m_status = Decoder::file_invalid; 104 return false; 105 } 106 107 if (!is_elf_file(m_elfHdr)) { 108 m_status = Decoder::file_invalid; 109 return false; 110 } 111 112 // walk elf file's section headers, and load string tables 113 Elf_Shdr shdr; 114 if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) { 115 if (Decoder::is_error(m_status)) return false; 116 117 for (int index = 0; index < m_elfHdr.e_shnum; index ++) { 118 if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { 119 m_status = Decoder::file_invalid; 120 return false; 121 } 122 // string table 123 if (shdr.sh_type == SHT_STRTAB) { 124 ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index); 125 if (table == NULL) { 126 m_status = Decoder::out_of_memory; 127 return false; 128 } 129 add_string_table(table); 130 } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { 131 ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); 132 if (table == NULL) { 133 m_status = Decoder::out_of_memory; 134 return false; 135 } 136 add_symbol_table(table); 137 } 138 } 139 } 140 return true; 141 } 142 143 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) { 144 // something already went wrong, just give up 145 if (Decoder::is_error(m_status)) { 146 return false; 147 } 148 ElfSymbolTable* symbol_table = m_symbol_tables; 149 int string_table_index; 150 int pos_in_string_table; 151 int off = INT_MAX; 152 bool found_symbol = false; 153 while (symbol_table != NULL) { 154 if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) { 155 found_symbol = true; 156 } 157 symbol_table = symbol_table->m_next; 158 } 159 if (!found_symbol) return false; 160 161 ElfStringTable* string_table = get_string_table(string_table_index); 162 163 if (string_table == NULL) { 164 m_status = Decoder::file_invalid; 165 return false; 166 } 167 if (offset) *offset = off; 168 169 return string_table->string_at(pos_in_string_table, buf, buflen); 170 } 171 172 173 void ElfFile::add_symbol_table(ElfSymbolTable* table) { 174 if (m_symbol_tables == NULL) { 175 m_symbol_tables = table; 176 } else { 177 table->m_next = m_symbol_tables; 178 m_symbol_tables = table; 179 } 180 } 181 182 void ElfFile::add_string_table(ElfStringTable* table) { 183 if (m_string_tables == NULL) { 184 m_string_tables = table; 185 } else { 186 table->m_next = m_string_tables; 187 m_string_tables = table; 188 } 189 } |