]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Disable libdwfl relocation of debug sections
authorRoland McGrath <roland@redhat.com>
Wed, 30 Jun 2010 00:17:39 +0000 (17:17 -0700)
committerRoland McGrath <roland@redhat.com>
Wed, 30 Jun 2010 00:17:39 +0000 (17:17 -0700)
13 files changed:
libdw/ChangeLog
libdw/dwarf_lineaddr.c
libdw/libdwP.h
libdw/relocate.c
libdwfl/ChangeLog
libdwfl/derelocate.c
libdwfl/dwfl_lineinfo.c
libdwfl/dwfl_module_getdwarf.c
libdwfl/dwfl_module_getelf.c
libdwfl/libdwflP.h
libdwfl/relocate.c
tests/ChangeLog
tests/line2addr.c

index 023621f49b89cfd1d33ff8138d925ae0081ca459..0d1854c6fba8573ecd20fda78a6168ad754dc32f 100644 (file)
@@ -1,5 +1,8 @@
 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.
index 1e0b3234303e128015d9407bbf876f3f3ce31a72..a1dc6ec681a26a0792f2bc19e41dd632f7b558aa 100644 (file)
@@ -77,3 +77,4 @@ dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp)
   return __libdw_relocate_shndx (line->cu->dbg,
                                 reloc[idx * 2 + 1], line->addr, addrp);
 }
+INTDEF (dwarf_lineaddr)
index 3633a28afa63d7f2e7f16bff7f8a3ef282b4a8d2..8d0cb6ad2251384c4ba8c62cd7854fe900c05265 100644 (file)
@@ -684,6 +684,7 @@ INTDECL (dwarf_hasattr)
 INTDECL (dwarf_haschildren)
 INTDECL (dwarf_haspc)
 INTDECL (dwarf_highpc)
+INTDECL (dwarf_lineaddr)
 INTDECL (dwarf_lowpc)
 INTDECL (dwarf_nextcu)
 INTDECL (dwarf_next_unit)
index 03671ce44d4b27f345037faed9e098da9a6d8b34..a7ee6b7508192708e0d171a3d648a066cab485e1 100644 (file)
@@ -84,7 +84,8 @@ __libdw_relocate_begin (Dwarf *dbg, Elf_Scn *relscn[IDX_last], bool incomplete)
          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
index e71e33d67f60723203104debcfd2aa869d8da4d1..38cf62a08ee1d55d489b9f79846bbb9ccfa08f42 100644 (file)
@@ -1,3 +1,19 @@
+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.
index 56ba25af27f3129cb68938500591ed23d5826474..ee869e061ba084ecc87b3c69e5ceb781f993c051 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -396,7 +396,7 @@ dwfl_module_address_section (Dwfl_Module *mod, Dwarf_Addr *address,
       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
index 920a2de9c1e3ed55fed40f5598d4584b37f9a2f5..8776482861b86bda5f2d87939d3bc4985c273ec8 100644 (file)
@@ -58,10 +58,17 @@ dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, int *linep, int *colp,
     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)
index 41ed0730e4a6b7e51772334c6c4d76f22c548f56..42d817a4ebe508594bed5d7d7e1b64e414f52a2c 100644 (file)
@@ -669,38 +669,6 @@ __libdwfl_module_getebl (Dwfl_Module *mod)
 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)
     {
@@ -708,6 +676,12 @@ load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
       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;
 
@@ -779,7 +753,7 @@ dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
        {
          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;
index 6414a9d3b887f4d43606b1ed9715d244e457a205..aa66c2cd292f161780f0d679702d153deeed1944 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -66,14 +66,14 @@ dwfl_module_getelf (Dwfl_Module *mod, GElf_Addr *loadbase)
          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);
                }
            }
        }
index e4c7e7c828a809e17b2352cf5689202448bbf32b..504b0fb1c651138cd148a058a127d38fce844af2 100644 (file)
@@ -251,21 +251,18 @@ extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function;
 /* 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.
index cb64fa26e36404767aa72973c8151cddcbb6221b..0313749a17f3bd166e19d7226dcf7c1a932ab1b9 100644 (file)
@@ -298,7 +298,7 @@ static Dwfl_Error
 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;
@@ -311,9 +311,9 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
     /* 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.  */
@@ -454,23 +454,22 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
                           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)
@@ -483,28 +482,27 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
                           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
@@ -553,7 +551,7 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
 
 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);
 
@@ -589,7 +587,7 @@ __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
          else
            result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
                                       &reloc_symtab, scn, shdr, tscn,
-                                      debug, !debug);
+                                      true);
        }
     }
 
@@ -599,7 +597,7 @@ __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
 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;
@@ -615,5 +613,5 @@ __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
                               gelf_getehdr (relocated, &ehdr_mem), shstrndx,
                               &reloc_symtab,
                               relocscn, gelf_getshdr (relocscn, &shdr_mem),
-                              tscn, false, partial));
+                              tscn, false));
 }
index 0176fb4951bd1de47b6039eca2d7336a6c3e4cf9..91ae9912a7ac422339f46edee948ab743de4d215 100644 (file)
@@ -1,3 +1,7 @@
+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.
index 5630da3c4d329d242378033648a5105bd61e4c01..aef129561ab8920d631c5645877506d60df9e99f 100644 (file)
@@ -1,4 +1,5 @@
-/* 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
@@ -92,7 +93,9 @@ handle_module (Dwfl_Module *mod __attribute__ ((unused)),
          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);