Mercurial > hg > graal-jvmci-8
comparison src/share/vm/utilities/elfFile.cpp @ 4803:d7e3846464d0
7071311: Decoder enhancement
Summary: Made decoder thread-safe
Reviewed-by: coleenp, kamg
author | zgu |
---|---|
date | Tue, 17 Jan 2012 13:08:52 -0500 |
parents | f08d439fab8c |
children | d2a62e0f25eb |
comparison
equal
deleted
inserted
replaced
4801:4f3ce9284781 | 4803:d7e3846464d0 |
---|---|
42 assert(filepath, "null file path"); | 42 assert(filepath, "null file path"); |
43 memset(&m_elfHdr, 0, sizeof(m_elfHdr)); | 43 memset(&m_elfHdr, 0, sizeof(m_elfHdr)); |
44 m_string_tables = NULL; | 44 m_string_tables = NULL; |
45 m_symbol_tables = NULL; | 45 m_symbol_tables = NULL; |
46 m_next = NULL; | 46 m_next = NULL; |
47 m_status = Decoder::no_error; | 47 m_status = NullDecoder::no_error; |
48 | 48 |
49 int len = strlen(filepath) + 1; | 49 int len = strlen(filepath) + 1; |
50 m_filepath = (const char*)os::malloc(len * sizeof(char)); | 50 m_filepath = (const char*)os::malloc(len * sizeof(char)); |
51 if (m_filepath != NULL) { | 51 if (m_filepath != NULL) { |
52 strcpy((char*)m_filepath, filepath); | 52 strcpy((char*)m_filepath, filepath); |
53 m_file = fopen(filepath, "r"); | 53 m_file = fopen(filepath, "r"); |
54 if (m_file != NULL) { | 54 if (m_file != NULL) { |
55 load_tables(); | 55 load_tables(); |
56 } else { | 56 } else { |
57 m_status = Decoder::file_not_found; | 57 m_status = NullDecoder::file_not_found; |
58 } | 58 } |
59 } else { | 59 } else { |
60 m_status = Decoder::out_of_memory; | 60 m_status = NullDecoder::out_of_memory; |
61 } | 61 } |
62 } | 62 } |
63 | 63 |
64 ElfFile::~ElfFile() { | 64 ElfFile::~ElfFile() { |
65 if (m_string_tables != NULL) { | 65 if (m_string_tables != NULL) { |
94 ELFDATANONE != hdr.e_ident[EI_DATA]); | 94 ELFDATANONE != hdr.e_ident[EI_DATA]); |
95 } | 95 } |
96 | 96 |
97 bool ElfFile::load_tables() { | 97 bool ElfFile::load_tables() { |
98 assert(m_file, "file not open"); | 98 assert(m_file, "file not open"); |
99 assert(m_status == Decoder::no_error, "already in error"); | 99 assert(!NullDecoder::is_error(m_status), "already in error"); |
100 | 100 |
101 // read elf file header | 101 // read elf file header |
102 if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) { | 102 if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) { |
103 m_status = Decoder::file_invalid; | 103 m_status = NullDecoder::file_invalid; |
104 return false; | 104 return false; |
105 } | 105 } |
106 | 106 |
107 if (!is_elf_file(m_elfHdr)) { | 107 if (!is_elf_file(m_elfHdr)) { |
108 m_status = Decoder::file_invalid; | 108 m_status = NullDecoder::file_invalid; |
109 return false; | 109 return false; |
110 } | 110 } |
111 | 111 |
112 // walk elf file's section headers, and load string tables | 112 // walk elf file's section headers, and load string tables |
113 Elf_Shdr shdr; | 113 Elf_Shdr shdr; |
114 if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) { | 114 if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) { |
115 if (m_status != Decoder::no_error) return false; | 115 if (NullDecoder::is_error(m_status)) return false; |
116 | 116 |
117 for (int index = 0; index < m_elfHdr.e_shnum; index ++) { | 117 for (int index = 0; index < m_elfHdr.e_shnum; index ++) { |
118 if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { | 118 if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { |
119 m_status = Decoder::file_invalid; | 119 m_status = NullDecoder::file_invalid; |
120 return false; | 120 return false; |
121 } | 121 } |
122 // string table | 122 // string table |
123 if (shdr.sh_type == SHT_STRTAB) { | 123 if (shdr.sh_type == SHT_STRTAB) { |
124 ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index); | 124 ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index); |
125 if (table == NULL) { | 125 if (table == NULL) { |
126 m_status = Decoder::out_of_memory; | 126 m_status = NullDecoder::out_of_memory; |
127 return false; | 127 return false; |
128 } | 128 } |
129 add_string_table(table); | 129 add_string_table(table); |
130 } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { | 130 } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { |
131 ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); | 131 ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); |
132 if (table == NULL) { | 132 if (table == NULL) { |
133 m_status = Decoder::out_of_memory; | 133 m_status = NullDecoder::out_of_memory; |
134 return false; | 134 return false; |
135 } | 135 } |
136 add_symbol_table(table); | 136 add_symbol_table(table); |
137 } | 137 } |
138 } | 138 } |
139 } | 139 } |
140 return true; | 140 return true; |
141 } | 141 } |
142 | 142 |
143 const char* ElfFile::decode(address addr, int* offset) { | 143 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) { |
144 // something already went wrong, just give up | 144 // something already went wrong, just give up |
145 if (m_status != Decoder::no_error) { | 145 if (NullDecoder::is_error(m_status)) { |
146 return NULL; | 146 return false; |
147 } | 147 } |
148 | |
149 ElfSymbolTable* symbol_table = m_symbol_tables; | 148 ElfSymbolTable* symbol_table = m_symbol_tables; |
150 int string_table_index; | 149 int string_table_index; |
151 int pos_in_string_table; | 150 int pos_in_string_table; |
152 int off = INT_MAX; | 151 int off = INT_MAX; |
153 bool found_symbol = false; | 152 bool found_symbol = false; |
154 while (symbol_table != NULL) { | 153 while (symbol_table != NULL) { |
155 if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) { | 154 if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) { |
156 found_symbol = true; | 155 found_symbol = true; |
157 } | 156 } |
158 symbol_table = symbol_table->m_next; | 157 symbol_table = symbol_table->m_next; |
159 } | 158 } |
160 if (!found_symbol) return NULL; | 159 if (!found_symbol) return false; |
161 | 160 |
162 ElfStringTable* string_table = get_string_table(string_table_index); | 161 ElfStringTable* string_table = get_string_table(string_table_index); |
162 | |
163 if (string_table == NULL) { | 163 if (string_table == NULL) { |
164 m_status = Decoder::file_invalid; | 164 m_status = NullDecoder::file_invalid; |
165 return NULL; | 165 return false; |
166 } | 166 } |
167 if (offset) *offset = off; | 167 if (offset) *offset = off; |
168 return string_table->string_at(pos_in_string_table); | 168 |
169 return string_table->string_at(pos_in_string_table, buf, buflen); | |
169 } | 170 } |
170 | 171 |
171 | 172 |
172 void ElfFile::add_symbol_table(ElfSymbolTable* table) { | 173 void ElfFile::add_symbol_table(ElfSymbolTable* table) { |
173 if (m_symbol_tables == NULL) { | 174 if (m_symbol_tables == NULL) { |