295 lines
10 KiB
Diff
295 lines
10 KiB
Diff
diff --git b/libdwfl/ChangeLog a/libdwfl/ChangeLog
|
|
index e1d00f1..01a2537 100644
|
|
--- b/libdwfl/ChangeLog
|
|
+++ a/libdwfl/ChangeLog
|
|
@@ -1,39 +1,3 @@
|
|
-2008-06-19 Andrew Cagney <cagney@redhat.com>
|
|
-
|
|
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Correctly update
|
|
- min_label.
|
|
-
|
|
-2008-06-07 Andrew Cagney <cagney@redhat.com>
|
|
-
|
|
- * dwfl_module_getdwarf.c (open_elf): Don't align the module's load
|
|
- address. Bug frysk/6599, redhat/450218.
|
|
-
|
|
- * dwfl_module_getsrc.c (dwfl_module_getsrc): Remove bias from
|
|
- address. Fix frysk/6600, redhat/450229.
|
|
-
|
|
-
|
|
-2008-05-21 Petr Machata <pmachata@redhat.com>
|
|
-
|
|
- * dwfl_module_getdwarf.c (open_elf): Assume that debuginfo of EXEC
|
|
- files has the same bias as the main file.
|
|
-
|
|
-2008-04-02 Petr Machata <pmachata@redhat.com>
|
|
-
|
|
- * dwfl_module_getdwarf.c (find_debuginfo): Return DWFL_E_CB when
|
|
- the callback results in an error.
|
|
- (find_file): Likewise.
|
|
-
|
|
-2008-03-24 Stan Cox <scox@redhat.com>
|
|
-
|
|
- * dwfl_module_getdwarf.c (load_symtab): Keep looking for an external
|
|
- symbol table even if we have a .dynsym. Should be fixed post 0.133.
|
|
-
|
|
-2008-03-13 Tim Moore <timoore@redhat.com>
|
|
-
|
|
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Start min_label
|
|
- from 0 to allow sizeless symbols below the address. Choose the
|
|
- best sizeless symbol.
|
|
-
|
|
2008-02-19 Roland McGrath <roland@redhat.com>
|
|
|
|
* relocate.c (relocate_section): Check for an unhandled relocation
|
|
diff --git b/libdwfl/dwfl_module_addrsym.c a/libdwfl/dwfl_module_addrsym.c
|
|
index 77033a6..f16de11 100644
|
|
--- b/libdwfl/dwfl_module_addrsym.c
|
|
+++ a/libdwfl/dwfl_module_addrsym.c
|
|
@@ -49,13 +49,10 @@
|
|
|
|
#include "libdwflP.h"
|
|
|
|
-#include <stdio.h>
|
|
-
|
|
const char *
|
|
dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
|
|
GElf_Sym *closest_sym, GElf_Word *shndxp)
|
|
{
|
|
- // fprintf(stderr, "looking up %lx\n", (long) addr);
|
|
int syments = INTUSE(dwfl_module_getsymtab) (mod);
|
|
if (syments < 0)
|
|
return NULL;
|
|
@@ -111,7 +108,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
|
|
GElf_Word sizeless_shndx = SHN_UNDEF;
|
|
|
|
/* Keep track of the lowest address a relevant sizeless symbol could have. */
|
|
- GElf_Addr min_label = 0;
|
|
+ GElf_Addr min_label = addr;
|
|
|
|
/* Look through the symbol table for a matching symbol. */
|
|
for (int i = 1; i < syments; ++i)
|
|
@@ -119,20 +116,15 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
|
|
GElf_Sym sym;
|
|
GElf_Word shndx;
|
|
const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx);
|
|
- // fprintf(stderr, "symbol %s at 0x%lx 0x%ld\n", name, (long) sym.st_value, (long) sym.st_size);
|
|
- /* Even if we don't choose this symbol, its existence excludes
|
|
- any sizeless symbol (assembly label) that is below its upper
|
|
- bound. */
|
|
- if (name != NULL && sym.st_value <= addr
|
|
- && sym.st_value + sym.st_size > min_label) {
|
|
- min_label = sym.st_value + sym.st_size;
|
|
- // fprintf(stderr, " min to %s size ends at %lx\n", name, (long) min_label);
|
|
- }
|
|
if (name != NULL
|
|
&& sym.st_value <= addr
|
|
&& (sym.st_size == 0 || addr - sym.st_value < sym.st_size))
|
|
{
|
|
- // fprintf(stderr, " candidate %s at 0x%lx 0x%ld\n", name, (long) sym.st_value, (long) sym.st_size);
|
|
+ /* Even if we don't choose this symbol, its existence
|
|
+ excludes any sizeless symbol (assembly label) that
|
|
+ is inside its bounds. */
|
|
+ if (sym.st_value + sym.st_size > addr)
|
|
+ min_label = sym.st_value + sym.st_size;
|
|
|
|
/* This symbol is a better candidate than the current one
|
|
if it's a named symbol, not a section or file symbol,
|
|
@@ -148,7 +140,6 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
|
|
{
|
|
if (sym.st_size != 0)
|
|
{
|
|
- // fprintf(stderr, " closest %s at %lx\n", name, (long)sym.st_value);
|
|
*closest_sym = sym;
|
|
closest_shndx = shndx;
|
|
closest_name = name;
|
|
@@ -159,29 +150,17 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
|
|
st_size. If no symbol with proper size includes
|
|
the address, we'll use the closest one that is in
|
|
the same section as ADDR. */
|
|
- if (sizeless_name == NULL
|
|
- || sizeless_sym.st_value < sym.st_value
|
|
- || (sizeless_sym.st_value == sym.st_value
|
|
- && strcmp(name, sizeless_name) < 0))
|
|
- {
|
|
- // fprintf(stderr, " sizeless %s at %lx\n", name, (long)sym.st_value);
|
|
- sizeless_sym = sym;
|
|
- sizeless_shndx = shndx;
|
|
- sizeless_name = name;
|
|
- }
|
|
+ sizeless_sym = sym;
|
|
+ sizeless_shndx = shndx;
|
|
+ sizeless_name = name;
|
|
}
|
|
}
|
|
/* When the beginning of its range is no closer,
|
|
- the end of its range might be.
|
|
- If symbols are identical, choose the first one in
|
|
- alphabetical order */
|
|
+ the end of its range might be. */
|
|
else if (sym.st_size != 0
|
|
&& closest_sym->st_value == sym.st_value
|
|
- && (closest_sym->st_size > sym.st_size
|
|
- || (closest_sym->st_size == sym.st_size
|
|
- && strcmp(name, closest_name) < 0)))
|
|
+ && closest_sym->st_size > sym.st_size)
|
|
{
|
|
- // fprintf(stderr, " alt closest %s at %lx\n", name, (long)sym.st_value);
|
|
*closest_sym = sym;
|
|
closest_shndx = shndx;
|
|
closest_name = name;
|
|
diff --git b/libdwfl/dwfl_module_getdwarf.c a/libdwfl/dwfl_module_getdwarf.c
|
|
index 1d75754..7dd9b53 100644
|
|
--- b/libdwfl/dwfl_module_getdwarf.c
|
|
+++ a/libdwfl/dwfl_module_getdwarf.c
|
|
@@ -82,26 +82,19 @@ open_elf (Dwfl_Module *mod, struct dwfl_file *file)
|
|
}
|
|
|
|
file->bias = 0;
|
|
- if (mod->e_type == ET_EXEC && file == &mod->debug)
|
|
- /* Prelink can change ET_EXEC's first loadable address, but it
|
|
- will not touch .text or any section where symbol information is
|
|
- relevant. Assume debugbias is the same as the main file. */
|
|
- file->bias = mod->main.bias;
|
|
- else
|
|
- for (uint_fast16_t i = 0; i < ehdr->e_phnum; ++i)
|
|
- {
|
|
- GElf_Phdr ph_mem;
|
|
- GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
|
|
- if (ph == NULL)
|
|
- goto elf_error;
|
|
- if (ph->p_type == PT_LOAD)
|
|
- {
|
|
- // Align the vaddr.
|
|
- Dwarf_Addr vaddr = ph->p_vaddr & -ph->p_align;
|
|
- file->bias = (mod->low_addr - vaddr);
|
|
- break;
|
|
- }
|
|
- }
|
|
+ for (uint_fast16_t i = 0; i < ehdr->e_phnum; ++i)
|
|
+ {
|
|
+ GElf_Phdr ph_mem;
|
|
+ GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
|
|
+ if (ph == NULL)
|
|
+ goto elf_error;
|
|
+ if (ph->p_type == PT_LOAD)
|
|
+ {
|
|
+ file->bias = ((mod->low_addr & -ph->p_align)
|
|
+ - (ph->p_vaddr & -ph->p_align));
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
|
|
mod->e_type = ehdr->e_type;
|
|
|
|
@@ -124,15 +117,6 @@ find_file (Dwfl_Module *mod)
|
|
mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod),
|
|
&mod->main.name,
|
|
&mod->main.elf);
|
|
-
|
|
- /* Bail out on error, but if there was a pre-primed file name left
|
|
- behind by the callback, try to open that file name. */
|
|
- if (mod->main.fd < 0 && mod->main.name == NULL)
|
|
- {
|
|
- mod->elferr = DWFL_E_CB;
|
|
- return;
|
|
- }
|
|
-
|
|
mod->elferr = open_elf (mod, &mod->main);
|
|
|
|
if (mod->elferr == DWFL_E_NOERROR && !mod->main.valid)
|
|
@@ -222,12 +206,6 @@ find_debuginfo (Dwfl_Module *mod)
|
|
debuglink_file,
|
|
debuglink_crc,
|
|
&mod->debug.name);
|
|
-
|
|
- /* Bail out on error, but if there was a pre-primed file name left
|
|
- behind by the callback, try to open that file name. */
|
|
- if (mod->debug.fd < 0 && mod->debug.name == NULL)
|
|
- return DWFL_E_CB;
|
|
-
|
|
return open_elf (mod, &mod->debug);
|
|
}
|
|
|
|
@@ -240,7 +218,6 @@ load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
|
|
Elf_Scn **symscn, Elf_Scn **xndxscn,
|
|
size_t *syments, GElf_Word *strshndx)
|
|
{
|
|
- bool symtab = false;
|
|
Elf_Scn *scn = NULL;
|
|
while ((scn = elf_nextscn (file->elf, scn)) != NULL)
|
|
{
|
|
@@ -249,7 +226,6 @@ load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
|
|
switch (shdr->sh_type)
|
|
{
|
|
case SHT_SYMTAB:
|
|
- symtab = true;
|
|
*symscn = scn;
|
|
*symfile = file;
|
|
*strshndx = shdr->sh_link;
|
|
@@ -259,8 +235,6 @@ load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
|
|
break;
|
|
|
|
case SHT_DYNSYM:
|
|
- if (symtab)
|
|
- break;
|
|
/* Use this if need be, but keep looking for SHT_SYMTAB. */
|
|
*symscn = scn;
|
|
*symfile = file;
|
|
@@ -270,7 +244,7 @@ load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
|
|
|
|
case SHT_SYMTAB_SHNDX:
|
|
*xndxscn = scn;
|
|
- if (symtab)
|
|
+ if (*symscn != NULL)
|
|
return DWFL_E_NOERROR;
|
|
break;
|
|
|
|
@@ -279,7 +253,7 @@ load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
|
|
}
|
|
}
|
|
|
|
- if (symtab)
|
|
+ if (*symscn != NULL)
|
|
/* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
|
|
return DWFL_E_NOERROR;
|
|
|
|
diff --git b/libdwfl/dwfl_module_getsrc.c a/libdwfl/dwfl_module_getsrc.c
|
|
index a413189..84c7eaa 100644
|
|
--- b/libdwfl/dwfl_module_getsrc.c
|
|
+++ a/libdwfl/dwfl_module_getsrc.c
|
|
@@ -63,8 +63,6 @@ dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr)
|
|
error = __libdwfl_cu_getsrclines (cu);
|
|
if (likely (error == DWFL_E_NOERROR))
|
|
{
|
|
- /* Remove bias. */
|
|
- addr = addr - bias;
|
|
/* The lines are sorted by address, so we can use binary search. */
|
|
size_t l = 0, u = cu->die.cu->lines->nlines;
|
|
while (l < u)
|
|
diff --git b/libelf/ChangeLog a/libelf/ChangeLog
|
|
index b7aeee4..ef7b37a 100644
|
|
--- b/libelf/ChangeLog
|
|
+++ a/libelf/ChangeLog
|
|
@@ -1,8 +1,3 @@
|
|
-2008-03-13 Tim Moore <timoore@redhat.com>
|
|
-
|
|
- * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Cast offset and
|
|
- size computation to uint64_t.
|
|
-
|
|
2008-02-19 Roland McGrath <roland@redhat.com>
|
|
|
|
* elf.h: Update from glibc.
|
|
diff --git b/libelf/elf_getdata_rawchunk.c a/libelf/elf_getdata_rawchunk.c
|
|
index 1b1b003..bea0f3f 100644
|
|
--- b/libelf/elf_getdata_rawchunk.c
|
|
+++ a/libelf/elf_getdata_rawchunk.c
|
|
@@ -79,7 +79,7 @@ elf_getdata_rawchunk (elf, offset, size, type)
|
|
}
|
|
|
|
if (unlikely (size > elf->maximum_size
|
|
- || (uint64_t)(elf->maximum_size - size) < (uint64_t)offset))
|
|
+ || (off64_t) (elf->maximum_size - size) < offset))
|
|
{
|
|
/* Invalid request. */
|
|
__libelf_seterrno (ELF_E_INVALID_OP);
|