2010-06-29 Roland McGrath <roland@redhat.com>
+ * dwarf_lineaddr.c: Add INTDEF.
+ * libdwP.h: Add INTDECL.
+
* dwarf_getsrc_relocatable.c: New file.
* Makefile.am (libdw_a_SOURCES): Add it.
* libdw.h: Declare it.
return __libdw_relocate_shndx (line->cu->dbg,
reloc[idx * 2 + 1], line->addr, addrp);
}
+INTDEF (dwarf_lineaddr)
INTDECL (dwarf_haschildren)
INTDECL (dwarf_haspc)
INTDECL (dwarf_highpc)
+INTDECL (dwarf_lineaddr)
INTDECL (dwarf_lowpc)
INTDECL (dwarf_nextcu)
INTDECL (dwarf_next_unit)
GElf_Shdr *shdr;
shdr = gelf_getshdr (scn, &shdr_mem);
assert (shdr == &shdr_mem);
- if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+ if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+ && shdr->sh_size != 0)
for (size_t i = 0; i < IDX_last; ++i)
if (relscn[i] == NULL && dbg->sectiondata[i] != NULL
&& (((Elf_Data_Scn * ) dbg->sectiondata[i])->s->index
+2010-06-29 Roland McGrath <roland@redhat.com>
+
+ * dwfl_lineinfo.c: Use dwarf_lineaddr.
+
+ * relocate.c (relocate_section): Remove PARTIAL flag argument.
+ Reverse sense of DEBUGSCN flag: if set, skip if target section
+ is a debugging section.
+ (__libdwfl_relocate): Update caller. Remove flag argument.
+ (__libdwfl_relocate_section): Likewise.
+ * libdwflP.h: Update decls.
+ * dwfl_module_getelf.c: Update caller.
+ * dwfl_module_getdwarf.c: Likewise.
+
+ * dwfl_module_getdwarf.c (load_dw): Don't relocate here.
+ Instead, hook into MOD->dw->relocate after dwarf_begin_elf.
+
2010-06-21 Roland McGrath <roland@redhat.com>
* open.c (__libdw_open_file): Close the fd when it's already mapped.
/* Recover relocatibility for addresses computed from debug information.
- Copyright (C) 2005-2009 Red Hat, Inc.
+ Copyright (C) 2005-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
Elf_Scn *tscn = mod->reloc_info->refs[idx].scn;
Elf_Scn *relocscn = mod->reloc_info->refs[idx].relocs;
Dwfl_Error result = __libdwfl_relocate_section (mod, mod->main.elf,
- relocscn, tscn, true);
+ relocscn, tscn);
if (likely (result == DWFL_E_NOERROR))
mod->reloc_info->refs[idx].relocs = NULL;
else
return NULL;
struct dwfl_cu *cu = dwfl_linecu (line);
- const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx];
+ Dwarf_Line *info = &cu->die.cu->lines->info[line->idx];
if (addr != NULL)
- *addr = info->addr + cu->mod->debug.bias;
+ {
+ if (INTUSE(dwarf_lineaddr) (info, addr))
+ {
+ __libdwfl_seterrno (DWFL_E_LIBDW);
+ return NULL;
+ }
+ *addr += cu->mod->debug.bias;
+ }
if (linep != NULL)
*linep = info->line;
if (colp != NULL)
static Dwfl_Error
load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
{
- if (mod->e_type == ET_REL && !debugfile->relocated)
- {
- const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
-
- /* The debugging sections have to be relocated. */
- if (cb->section_address == NULL)
- return DWFL_E_NOREL;
-
- Dwfl_Error error = __libdwfl_module_getebl (mod);
- if (error != DWFL_E_NOERROR)
- return error;
-
- find_symtab (mod);
- Dwfl_Error result = mod->symerr;
- if (result == DWFL_E_NOERROR)
- result = __libdwfl_relocate (mod, debugfile->elf, true);
- if (result != DWFL_E_NOERROR)
- return result;
-
- /* Don't keep the file descriptors around. */
- if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
- {
- close (mod->main.fd);
- mod->main.fd = -1;
- }
- if (debugfile->fd != -1 && elf_cntl (debugfile->elf, ELF_C_FDREAD) == 0)
- {
- close (debugfile->fd);
- debugfile->fd = -1;
- }
- }
-
mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL);
if (mod->dw == NULL)
{
return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err);
}
+ if (mod->dw->relocate != NULL)
+ {
+ assert (mod->e_type == ET_REL);
+ // mod->dw->relocate->dwflmod = mod;
+ }
+
/* Until we have iterated through all CU's, we might do lazy lookups. */
mod->lazycu = 1;
{
mod->debug.relocated = true;
if (mod->debug.elf != mod->main.elf)
- (void) __libdwfl_relocate (mod, mod->debug.elf, false);
+ (void) __libdwfl_relocate (mod, mod->debug.elf);
}
*bias = mod->debug.bias;
/* Find debugging and symbol information for a module in libdwfl.
- Copyright (C) 2009 Red Hat, Inc.
+ Copyright (C) 2009-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
mod->main.relocated = true;
if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR))
{
- (void) __libdwfl_relocate (mod, mod->main.elf, false);
+ (void) __libdwfl_relocate (mod, mod->main.elf);
if (mod->debug.elf == mod->main.elf)
mod->debug.relocated = true;
else if (mod->debug.elf != NULL && ! mod->debug.relocated)
{
mod->debug.relocated = true;
- (void) __libdwfl_relocate (mod, mod->debug.elf, false);
+ (void) __libdwfl_relocate (mod, mod->debug.elf);
}
}
}
/* Find the main ELF file, update MOD->elferr and/or MOD->main.elf. */
extern void __libdwfl_getelf (Dwfl_Module *mod) internal_function;
-/* Process relocations in debugging sections in an ET_REL file.
+/* Process relocations in non-debugging sections in an ET_REL file.
FILE must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ,
to make it possible to relocate the data in place (or ELF_C_RDWR or
ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk). After
- this, dwarf_begin_elf on FILE will read the relocated data.
-
- When DEBUG is false, apply partial relocation to all sections. */
-extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file, bool debug)
+ this, libelf calls on FILE will read the relocated data. */
+extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file)
internal_function;
/* Process (simple) relocations in arbitrary section TSCN of an ET_REL file.
RELOCSCN is SHT_REL or SHT_RELA and TSCN is its sh_info target section. */
extern Dwfl_Error __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
- Elf_Scn *relocscn, Elf_Scn *tscn,
- bool partial)
+ Elf_Scn *relocscn, Elf_Scn *tscn);
internal_function;
/* Adjust *VALUE from section-relative to absolute.
relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
size_t shstrndx, struct reloc_symtab_cache *reloc_symtab,
Elf_Scn *scn, GElf_Shdr *shdr,
- Elf_Scn *tscn, bool debugscn, bool partial)
+ Elf_Scn *tscn, bool check_debugscn)
{
/* First, fetch the name of the section these relocations apply to. */
GElf_Shdr tshdr_mem;
/* No contents to relocate. */
return DWFL_E_NOERROR;
- if (debugscn && ! ebl_debugscn_p (mod->ebl, tname))
- /* This relocation section is not for a debugging section.
- Nothing to do here. */
+ if (check_debugscn && ebl_debugscn_p (mod->ebl, tname))
+ /* This relocation section is for a debugging section. We don't touch
+ these here, since libdw proper already handles them lazily. */
return DWFL_E_NOERROR;
/* Fetch the section data that needs the relocations applied. */
GELF_R_TYPE (r->r_info),
GELF_R_SYM (r->r_info));
check_badreltype ();
- if (partial)
- switch (result)
- {
- case DWFL_E_NOERROR:
- /* We applied the relocation. Elide it. */
- memset (&rel_mem, 0, sizeof rel_mem);
- gelf_update_rel (reldata, relidx, &rel_mem);
- ++complete;
- break;
- case DWFL_E_BADRELTYPE:
- case DWFL_E_RELUNDEF:
- /* We couldn't handle this relocation. Skip it. */
- result = DWFL_E_NOERROR;
- break;
- default:
- break;
- }
+ switch (result)
+ {
+ case DWFL_E_NOERROR:
+ /* We applied the relocation. Elide it. */
+ memset (&rel_mem, 0, sizeof rel_mem);
+ gelf_update_rel (reldata, relidx, &rel_mem);
+ ++complete;
+ break;
+ case DWFL_E_BADRELTYPE:
+ case DWFL_E_RELUNDEF:
+ /* We couldn't handle this relocation. Skip it. */
+ result = DWFL_E_NOERROR;
+ break;
+ default:
+ break;
+ }
}
else
for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
GELF_R_TYPE (r->r_info),
GELF_R_SYM (r->r_info));
check_badreltype ();
- if (partial)
- switch (result)
- {
- case DWFL_E_NOERROR:
- /* We applied the relocation. Elide it. */
- memset (&rela_mem, 0, sizeof rela_mem);
- gelf_update_rela (reldata, relidx, &rela_mem);
- ++complete;
- break;
- case DWFL_E_BADRELTYPE:
- case DWFL_E_RELUNDEF:
- /* We couldn't handle this relocation. Skip it. */
- result = DWFL_E_NOERROR;
- break;
- default:
- break;
- }
+ switch (result)
+ {
+ case DWFL_E_NOERROR:
+ /* We applied the relocation. Elide it. */
+ memset (&rela_mem, 0, sizeof rela_mem);
+ gelf_update_rela (reldata, relidx, &rela_mem);
+ ++complete;
+ break;
+ case DWFL_E_BADRELTYPE:
+ case DWFL_E_RELUNDEF:
+ /* We couldn't handle this relocation. Skip it. */
+ result = DWFL_E_NOERROR;
+ break;
+ default:
+ break;
+ }
}
if (likely (result == DWFL_E_NOERROR))
{
- if (!partial || complete == nrels)
+ if (complete == nrels)
/* Mark this relocation section as being empty now that we have
done its work. This affects unstrip -R, so e.g. it emits an
empty .rela.debug_info along with a .debug_info that has
Dwfl_Error
internal_function
-__libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
+__libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile)
{
assert (mod->e_type == ET_REL);
else
result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
&reloc_symtab, scn, shdr, tscn,
- debug, !debug);
+ true);
}
}
Dwfl_Error
internal_function
__libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
- Elf_Scn *relocscn, Elf_Scn *tscn, bool partial)
+ Elf_Scn *relocscn, Elf_Scn *tscn)
{
GElf_Ehdr ehdr_mem;
GElf_Shdr shdr_mem;
gelf_getehdr (relocated, &ehdr_mem), shstrndx,
&reloc_symtab,
relocscn, gelf_getshdr (relocscn, &shdr_mem),
- tscn, false, partial));
+ tscn, false));
}
+2010-06-29 Roland McGrath <roland@redhat.com>
+
+ * line2addr.c (handle_module): Diagnose dwfl_lineinfo failure.
+
2010-06-04 Roland McGrath <roland@redhat.com>
* run-unstrip-test.sh: Also test modifying the file in place.
-/* Copyright (C) 2005 Red Hat, Inc.
+/* Test program translating source lines into addresses.
+ Copyright (C) 2005-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
int line = a->line, col = 0;
const char *file = dwfl_lineinfo (lines[inner], &addr, &line, &col,
NULL, NULL);
- if (file != NULL)
+ if (file == NULL)
+ printf ("%s => dwfl_lineinfo: %s\n", a->arg, dwfl_errmsg (-1));
+ else
{
printf ("%s -> ", a->arg);
print_address (mod, addr);