From 5007d80b093ad435efbcc9ea97dfa6f4c13757f2 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 20 Mar 2009 10:32:37 +0000 Subject: [PATCH] Check whether the symbol table is in the main object file or the debug object file and use that information to decide which svma and bias values to use when working out what section a symbol refers to. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9469 --- coregrind/m_debuginfo/readelf.c | 100 ++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index e8d3ba1531..84a54128b5 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -206,6 +206,7 @@ Bool get_elf_symbol_info ( ElfXX_Sym* sym, /* ELF symbol */ Char* sym_name, /* name */ Addr sym_svma, /* address as stated in the object file */ + Bool symtab_in_debug, /* symbol table is in the debug file */ UChar* opd_img, /* oimage of .opd sec (ppc64-linux only) */ PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */ /* OUTPUTS */ @@ -224,6 +225,8 @@ Bool get_elf_symbol_info ( Bool is_in_opd; # endif Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss; + Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma; + PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias; /* Set defaults */ *sym_name_out = sym_name; @@ -245,67 +248,85 @@ Bool get_elf_symbol_info ( || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT ); - /* Now bias sym_avma_out accordingly */ -#if 0 - /* This works, but seems a bit crude */ - if (ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT) { - *is_text_out = False; - *sym_avma_out += di->data_bias; + /* Work out the svma and bias for each section as it will appear in + addresses in the symbol table. */ + if (symtab_in_debug) { + text_svma = di->text_debug_svma; + text_bias = di->text_debug_bias; + data_svma = di->data_debug_svma; + data_bias = di->data_debug_bias; + sdata_svma = di->sdata_debug_svma; + sdata_bias = di->sdata_debug_bias; + rodata_svma = di->rodata_debug_svma; + rodata_bias = di->rodata_debug_bias; + bss_svma = di->bss_debug_svma; + bss_bias = di->bss_debug_bias; + sbss_svma = di->sbss_debug_svma; + sbss_bias = di->sbss_debug_bias; } else { - *is_text_out = True; - *sym_avma_out += di->text_bias; + text_svma = di->text_svma; + text_bias = di->text_bias; + data_svma = di->data_svma; + data_bias = di->data_bias; + sdata_svma = di->sdata_svma; + sdata_bias = di->sdata_bias; + rodata_svma = di->rodata_svma; + rodata_bias = di->rodata_bias; + bss_svma = di->bss_svma; + bss_bias = di->bss_bias; + sbss_svma = di->sbss_svma; + sbss_bias = di->sbss_bias; } -#else - /* Try to figure out exactly which section the symbol is from and - bias accordingly. Screws up if the previously deduced section - svma address ranges are wrong. */ + + /* Now bias sym_avma_out accordingly by figuring out exactly which + section the symbol is from and bias accordingly. Screws up if + the previously deduced section svma address ranges are wrong. */ if (di->text_present && di->text_size > 0 - && sym_svma >= di->text_svma - && sym_svma < di->text_svma + di->text_size) { + && sym_svma >= text_svma + && sym_svma < text_svma + di->text_size) { *is_text_out = True; - *sym_avma_out += di->text_bias; + *sym_avma_out += text_bias; } else if (di->data_present && di->data_size > 0 - && sym_svma >= di->data_svma - && sym_svma < di->data_svma + di->data_size) { + && sym_svma >= data_svma + && sym_svma < data_svma + di->data_size) { *is_text_out = False; - *sym_avma_out += di->data_bias; + *sym_avma_out += data_bias; } else if (di->sdata_present && di->sdata_size > 0 - && sym_svma >= di->sdata_svma - && sym_svma < di->sdata_svma + di->sdata_size) { + && sym_svma >= sdata_svma + && sym_svma < sdata_svma + di->sdata_size) { *is_text_out = False; - *sym_avma_out += di->sdata_bias; + *sym_avma_out += sdata_bias; } else if (di->rodata_present && di->rodata_size > 0 - && sym_svma >= di->rodata_svma - && sym_svma < di->rodata_svma + di->rodata_size) { + && sym_svma >= rodata_svma + && sym_svma < rodata_svma + di->rodata_size) { *is_text_out = False; - *sym_avma_out += di->rodata_bias; + *sym_avma_out += rodata_bias; } else if (di->bss_present && di->bss_size > 0 - && sym_svma >= di->bss_svma - && sym_svma < di->bss_svma + di->bss_size) { + && sym_svma >= bss_svma + && sym_svma < bss_svma + di->bss_size) { *is_text_out = False; - *sym_avma_out += di->bss_bias; + *sym_avma_out += bss_bias; } else if (di->sbss_present && di->sbss_size > 0 - && sym_svma >= di->sbss_svma - && sym_svma < di->sbss_svma + di->sbss_size) { + && sym_svma >= sbss_svma + && sym_svma < sbss_svma + di->sbss_size) { *is_text_out = False; - *sym_avma_out += di->sbss_bias; + *sym_avma_out += sbss_bias; } else { /* Assume it's in .text. Is this a good idea? */ *is_text_out = True; - *sym_avma_out += di->text_bias; + *sym_avma_out += text_bias; } -#endif # if defined(VGP_ppc64_linux) /* Allow STT_NOTYPE in the very special case where we're running on @@ -522,7 +543,7 @@ Bool get_elf_symbol_info ( # if defined(VGP_ppc64_linux) /* It's crucial that we never add symbol addresses in the .opd section. This would completely mess up function redirection and - intercepting. This assert ensures that any symbols that make it + intercepting. This assert ensures that anysymbols that make it into the symbol table on ppc64-linux don't point into .opd. */ if (di->opd_present && di->opd_size > 0) { vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma @@ -543,6 +564,7 @@ void read_elf_symtab__normal( struct _DebugInfo* di, UChar* tab_name, ElfXX_Sym* symtab_img, SizeT symtab_szB, UChar* strtab_img, SizeT strtab_szB, + Bool symtab_in_debug, UChar* opd_img /* ppc64-linux only */ ) { @@ -577,6 +599,7 @@ void read_elf_symtab__normal( show_raw_elf_symbol(i, sym, sym_name, sym_svma, False); if (get_elf_symbol_info(di, sym, sym_name, sym_svma, + symtab_in_debug, opd_img, di->text_bias, &sym_name_really, &sym_avma_really, @@ -641,6 +664,7 @@ void read_elf_symtab__ppc64_linux( struct _DebugInfo* di, UChar* tab_name, ElfXX_Sym* symtab_img, SizeT symtab_szB, UChar* strtab_img, SizeT strtab_szB, + Bool symtab_in_debug, UChar* opd_img /* ppc64-linux only */ ) { @@ -686,6 +710,7 @@ void read_elf_symtab__ppc64_linux( show_raw_elf_symbol(i, sym, sym_name, sym_svma, True); if (get_elf_symbol_info(di, sym, sym_name, sym_svma, + symtab_in_debug, opd_img, di->text_bias, &sym_name_really, &sym_avma_really, @@ -1934,21 +1959,24 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) void (*read_elf_symtab)(struct _DebugInfo*,UChar*, ElfXX_Sym*,SizeT, UChar*,SizeT, - UChar*); + Bool,UChar*); + Bool symtab_in_debug; # if defined(VGP_ppc64_linux) read_elf_symtab = read_elf_symtab__ppc64_linux; # else read_elf_symtab = read_elf_symtab__normal; # endif + symtab_in_debug = (Addr)symtab_img >= dimage + && (Addr)symtab_img < dimage + n_dimage; read_elf_symtab(di, "symbol table", symtab_img, symtab_sz, strtab_img, strtab_sz, - opd_img); + symtab_in_debug, opd_img); read_elf_symtab(di, "dynamic symbol table", dynsym_img, dynsym_sz, dynstr_img, dynstr_sz, - opd_img); + False, opd_img); } /* Read .eh_frame (call-frame-info) if any */ -- 2.47.3