summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillermo E. Martinez <guillermo.e.martinez@oracle.com>2022-05-06 20:50:25 -0500
committerDodji Seketeli <dodji@redhat.com>2022-05-13 14:34:47 +0200
commit00a9ce61fcde19938dce08e316dd916e422687e0 (patch)
tree730d32d6fc3e43a9bbe535ed1a547636797889ab
parentctf-reader: shows incomplete summary changes (diff)
downloadlibabigail-00a9ce61fcde19938dce08e316dd916e422687e0.tar.gz
libabigail-00a9ce61fcde19938dce08e316dd916e422687e0.tar.bz2
libabigail-00a9ce61fcde19938dce08e316dd916e422687e0.tar.xz
ctf-reader: CTF debug info for some symbols is not found
Running `abidw --ctf' tool for some executable ELF files, seems that ctf reader is unable to get debug information for some symbols so, they will not be neither the corpus nor in abixml file. This is happening because internally the reader uses `ctf_arc_bufopen' expecting as argument the sections: symbol table (.dynsym) and string table (.dynstr) for ELF types: ET_{EXEC,DYN}, currently those sections are read by `elf_helpers' but it uses .symtab when it is present and `symtab_shdr->sh_link' to get .strtab, instead. * src/abg-ctf-reader.cc (read_context::is_elf_exec): Remove data member. (ctf_reader::process_ctf_qualified_type): Add condition to avoid use qualifier in functions. (ctf_reader::process_ctf_archive): Use `ctf_lookup_by_symbol_name' to find debug information when `ctf_lookup_variable' was not lucky iff `corpus::CTF_ORIGIN'. (ctf_reader::slurp_elf_info): Use `elf_helpers::find_section_by_name' to read .dynsym and .dynstr when {EXEC,DYN}. * src/abg-elf-helpers.h (elf_helpers::find_section_by_name): Add new declaration. * src/abg-elf-helpers.cc (elf_helpers::find_section_by_name): Add new definition. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
-rw-r--r--src/abg-ctf-reader.cc53
-rw-r--r--src/abg-elf-helpers.cc29
-rw-r--r--src/abg-elf-helpers.h3
3 files changed, 67 insertions, 18 deletions
diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc
index a6a0b74e..89dea276 100644
--- a/src/abg-ctf-reader.cc
+++ b/src/abg-ctf-reader.cc
@@ -70,8 +70,6 @@ public:
70 Elf *elf_handler; 70 Elf *elf_handler;
71 int elf_fd; 71 int elf_fd;
72 72
73 /// set when ELF is ET_EXEC
74 bool is_elf_exec;
75 73
76 /// The symtab read from the ELF file. 74 /// The symtab read from the ELF file.
77 symtab_reader::symtab_sptr symtab; 75 symtab_reader::symtab_sptr symtab;
@@ -253,9 +251,13 @@ public:
253 251
254 /// Constructor. 252 /// Constructor.
255 /// 253 ///
256 /// ctfa data member can be used per courpus group.
257 ///
258 /// @param elf_path the path to the ELF file. 254 /// @param elf_path the path to the ELF file.
255 ///
256 /// @param environment the environment used by the current context.
257 /// This environment contains resources needed by the reader and by
258 /// the types and declarations that are to be created later. Note
259 /// that ABI artifacts that are to be compared all need to be
260 /// created within the same environment.
259 read_context(const string& elf_path, ir::environment *env) : 261 read_context(const string& elf_path, ir::environment *env) :
260 ctfa(NULL) 262 ctfa(NULL)
261 { 263 {
@@ -284,7 +286,6 @@ public:
284 ir_env = env; 286 ir_env = env;
285 elf_handler = NULL; 287 elf_handler = NULL;
286 elf_fd = -1; 288 elf_fd = -1;
287 is_elf_exec = false;
288 symtab.reset(); 289 symtab.reset();
289 cur_corpus_group_.reset(); 290 cur_corpus_group_.reset();
290 exported_decls_builder_ = 0; 291 exported_decls_builder_ = 0;
@@ -908,8 +909,11 @@ process_ctf_qualified_type(read_context *ctxt,
908 else 909 else
909 ABG_ASSERT_NOT_REACHED; 910 ABG_ASSERT_NOT_REACHED;
910 911
911 result.reset(new qualified_type_def(utype, qualifiers, location())); 912 // qualifiers are not be use in functions
913 if (is_function_type(utype))
914 return result;
912 915
916 result.reset(new qualified_type_def(utype, qualifiers, location()));
913 if (result) 917 if (result)
914 { 918 {
915 decl_base_sptr qualified_type_decl = get_type_declaration(result); 919 decl_base_sptr qualified_type_decl = get_type_declaration(result);
@@ -1226,16 +1230,16 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
1226 std::string sym_name = symbol->get_name(); 1230 std::string sym_name = symbol->get_name();
1227 ctf_id_t ctf_sym_type; 1231 ctf_id_t ctf_sym_type;
1228 1232
1229 if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN) 1233 ctf_sym_type = ctf_lookup_variable(ctf_dict, sym_name.c_str());
1230 || ctxt->is_elf_exec) 1234 if (ctf_sym_type == (ctf_id_t) -1
1231 ctf_sym_type= ctf_lookup_variable (ctf_dict, sym_name.c_str()); 1235 && !(corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN))
1232 else 1236 // lookup in function objects
1233 ctf_sym_type = ctf_lookup_by_symbol_name(ctf_dict, sym_name.c_str()); 1237 ctf_sym_type = ctf_lookup_by_symbol_name(ctf_dict, sym_name.c_str());
1234 1238
1235 if (ctf_sym_type == (ctf_id_t) -1) 1239 if (ctf_sym_type == (ctf_id_t) -1)
1236 continue; 1240 continue;
1237 1241
1238 if (ctf_type_kind (ctf_dict, ctf_sym_type) != CTF_K_FUNCTION) 1242 if (ctf_type_kind(ctf_dict, ctf_sym_type) != CTF_K_FUNCTION)
1239 { 1243 {
1240 const char *var_name = sym_name.c_str(); 1244 const char *var_name = sym_name.c_str();
1241 type_base_sptr var_type = lookup_type(ctxt, corp, ir_translation_unit, 1245 type_base_sptr var_type = lookup_type(ctxt, corp, ir_translation_unit,
@@ -1275,7 +1279,7 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
1275 func_declaration->set_symbol(symbol); 1279 func_declaration->set_symbol(symbol);
1276 add_decl_to_scope(func_declaration, 1280 add_decl_to_scope(func_declaration,
1277 ir_translation_unit->get_global_scope()); 1281 ir_translation_unit->get_global_scope());
1278 func_declaration->set_is_in_public_symbol_table(true); 1282 func_declaration->set_is_in_public_symbol_table(true);
1279 ctxt->maybe_add_fn_to_exported_decls(func_declaration.get()); 1283 ctxt->maybe_add_fn_to_exported_decls(func_declaration.get());
1280 } 1284 }
1281 } 1285 }
@@ -1366,10 +1370,13 @@ fill_ctf_section(Elf_Scn *elf_section, ctf_sect_t *ctf_section)
1366static int 1370static int
1367slurp_elf_info(read_context *ctxt, corpus_sptr corp) 1371slurp_elf_info(read_context *ctxt, corpus_sptr corp)
1368{ 1372{
1369 /* Set the ELF architecture. */ 1373 Elf_Scn *symtab_scn;
1374 Elf_Scn *ctf_scn;
1375 Elf_Scn *strtab_scn;
1370 GElf_Ehdr eh_mem; 1376 GElf_Ehdr eh_mem;
1371 GElf_Ehdr *ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem); 1377 GElf_Ehdr *ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem);
1372 ctxt->is_elf_exec = (ehdr->e_type == ET_EXEC); 1378
1379 /* Set the ELF architecture. */
1373 corp->set_architecture_name(elf_helpers::e_machine_to_string(ehdr->e_machine)); 1380 corp->set_architecture_name(elf_helpers::e_machine_to_string(ehdr->e_machine));
1374 1381
1375 /* Read the symtab from the ELF file and set it in the corpus. */ 1382 /* Read the symtab from the ELF file and set it in the corpus. */
@@ -1382,10 +1389,20 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp)
1382 return 1; 1389 return 1;
1383 1390
1384 /* Get the raw ELF section contents for libctf. */ 1391 /* Get the raw ELF section contents for libctf. */
1385 Elf_Scn *ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS); 1392 ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS);
1386 Elf_Scn *symtab_scn = elf_helpers::find_symbol_table_section(ctxt->elf_handler); 1393
1387 Elf_Scn *strtab_scn = elf_helpers::find_strtab_for_symtab_section(ctxt->elf_handler, 1394 // ET_{EXEC,DYN} needs .dyn{sym,str} in ctf_arc_bufopen
1388 symtab_scn); 1395 const char *symtab_name = ".dynsym";
1396 const char *strtab_name = ".dynstr";
1397
1398 if (ehdr->e_type == ET_REL)
1399 {
1400 symtab_name = ".symtab";
1401 strtab_name = ".strtab";
1402 }
1403
1404 symtab_scn = elf_helpers::find_section_by_name(ctxt->elf_handler, symtab_name);
1405 strtab_scn = elf_helpers::find_section_by_name(ctxt->elf_handler, strtab_name);
1389 1406
1390 if (ctf_scn == NULL || symtab_scn == NULL || strtab_scn == NULL) 1407 if (ctf_scn == NULL || symtab_scn == NULL || strtab_scn == NULL)
1391 return 0; 1408 return 0;
diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc
index 787a05ff..a1fd4e6c 100644
--- a/src/abg-elf-helpers.cc
+++ b/src/abg-elf-helpers.cc
@@ -296,6 +296,35 @@ e_machine_to_string(GElf_Half e_machine)
296 } 296 }
297} 297}
298 298
299/// Find and return a section by its name.
300///
301/// @param elf_handle the elf handle to use.
302///
303/// @return the section found, nor nil if none was found.
304Elf_Scn*
305find_section_by_name(Elf* elf_handle, const std::string& name)
306{
307 size_t section_header_string_index = 0;
308 if (elf_getshdrstrndx (elf_handle, &section_header_string_index) < 0)
309 return 0;
310
311 Elf_Scn* section = 0;
312 GElf_Shdr header_mem, *header;
313 while ((section = elf_nextscn(elf_handle, section)) != 0)
314 {
315 header = gelf_getshdr(section, &header_mem);
316 if (header == NULL)
317 continue;
318
319 const char* section_name =
320 elf_strptr(elf_handle, section_header_string_index, header->sh_name);
321 if (section_name && name == section_name)
322 return section;
323 }
324
325 return 0;
326}
327
299/// Find and return a section by its name and its type. 328/// Find and return a section by its name and its type.
300/// 329///
301/// @param elf_handle the elf handle to use. 330/// @param elf_handle the elf handle to use.
diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h
index afaff24a..ee406863 100644
--- a/src/abg-elf-helpers.h
+++ b/src/abg-elf-helpers.h
@@ -50,6 +50,9 @@ find_section(Elf* elf_handle,
50 Elf64_Word section_type); 50 Elf64_Word section_type);
51 51
52Elf_Scn* 52Elf_Scn*
53find_section_by_name(Elf* elf_handle, const std::string& name);
54
55Elf_Scn*
53find_section(Elf* elf_handle, Elf64_Word section_type); 56find_section(Elf* elf_handle, Elf64_Word section_type);
54 57
55Elf_Scn* 58Elf_Scn*