]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
src/
authorRoland McGrath <roland@redhat.com>
Thu, 7 Aug 2008 08:39:41 +0000 (08:39 +0000)
committerRoland McGrath <roland@redhat.com>
Thu, 7 Aug 2008 08:39:41 +0000 (08:39 +0000)
(find_symbol): Likewise.
Convert plain number, or handle strings like "(section)+offset"
or "symbol+offset".

27 files changed:
backends/ChangeLog
backends/Makefile.am
backends/i386_init.c
backends/i386_syscall.c [new file with mode: 0644]
backends/linux-core-note.c
backends/ppc64_init.c
backends/ppc_corenote.c
backends/ppc_init.c
backends/ppc_syscall.c [new file with mode: 0644]
backends/x86_64_init.c
backends/x86_64_syscall.c [new file with mode: 0644]
libdwfl/ChangeLog
libdwfl/dwfl_build_id_find_elf.c
libdwfl/dwfl_module_addrsym.c
libdwfl/linux-kernel-modules.c
libebl/ChangeLog
libebl/Makefile.am
libebl/ebl-hooks.h
libebl/ebl_syscall_abi.c [new file with mode: 0644]
libebl/eblauxvinfo.c
libebl/eblopenbackend.c
libebl/libebl.h
libelf/ChangeLog
libelf/elf.h
src/ChangeLog
src/addr2line.c
src/readelf.c

index 06e9041f82c8a48065f046fb2cb9326409951f8e..96b64794f7fb808406dc58029597fd57065f5d3c 100644 (file)
@@ -1,3 +1,22 @@
+2008-08-01  Roland McGrath  <roland@redhat.com>
+
+       * linux-core-note.c (prstatus_items): Use 'B' instead of 'b'
+       for sigpend and sighold.
+
+2008-07-04  Roland McGrath  <roland@redhat.com>
+
+       * i386_syscall.c: New file.
+       * x86_64_syscall.c: New file.
+       * ppc_syscall.c: New file.
+       * Makefile.am (i386_SRCS, x86_64_SRCS, ppc_SRCS, ppc64_SRCS): Add them.
+       * i386_init.c (i386_init): Initialize syscall_abi hook.
+       * x86_64_init.c (x86_64_init): Likewise.
+       * ppc_init.c (ppc_init): Likewise.
+       * ppc64_init.c (ppc64_init): Likewise.
+
+       * ppc_corenote.c (PRSTATUS_REGSET_ITEMS): Add nip.
+       Fix offset calculation for 64-bit case.
+
 2008-04-04  Roland McGrath  <roland@redhat.com>
 
        * alpha_symbol.c (alpha_check_special_section): New function.
index 75eacde9a3fbf5bd45dfaddb1233921ac1399eae..ebf6b09e4690561399d609564e6cd7e6571620da 100644 (file)
@@ -61,7 +61,7 @@ textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
 
 
 i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c \
-           i386_retval.c i386_regs.c i386_auxv.c
+           i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c
 cpu_i386 = ../libcpu/libcpu_i386.a
 libebl_i386_pic_a_SOURCES = $(i386_SRCS)
 am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
@@ -71,7 +71,7 @@ libebl_sh_pic_a_SOURCES = $(sh_SRCS)
 am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
 
 x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c \
-             x86_64_retval.c x86_64_regs.c i386_auxv.c
+             x86_64_retval.c x86_64_regs.c i386_auxv.c x86_64_syscall.c
 cpu_x86_64 = ../libcpu/libcpu_x86_64.a
 libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
 am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
@@ -95,12 +95,12 @@ libebl_sparc_pic_a_SOURCES = $(sparc_SRCS)
 am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
 
 ppc_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c ppc_regs.c \
-          ppc_corenote.c ppc_auxv.c ppc_attrs.c
+          ppc_corenote.c ppc_auxv.c ppc_attrs.c ppc_syscall.c
 libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
 am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
 
 ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
-            ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c
+            ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c
 libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
 am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
 
index bf6c130c305a68734cd1828b86bbd92b6cdcc488..f046dfb69e9de1b05f9594cd78fdaf2a842b1ef3 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of i386 specific backend library.
-   Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -56,6 +56,7 @@ i386_init (elf, machine, eh, ehlen)
   HOOK (eh, debugscn_p);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
   HOOK (eh, auxv_info);
   HOOK (eh, disasm);
 
diff --git a/backends/i386_syscall.c b/backends/i386_syscall.c
new file mode 100644 (file)
index 0000000..4d6e438
--- /dev/null
@@ -0,0 +1,47 @@
+/* Linux/i386 system call ABI in DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+int
+i386_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+                 int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = 4;                     /* %esp */
+  *pc = 8;                     /* %eip */
+  *callno = 0;                 /* %eax */
+  args[0] = 3;                 /* %ebx */
+  args[1] = 1;                 /* %ecx */
+  args[2] = 2;                 /* %edx */
+  args[3] = 6;                 /* %esi */
+  args[4] = 7;                 /* %edi */
+  args[5] = 5;                 /* %ebp */
+  return 0;
+}
index 3dc413738f6fd095997af279abbfee656d703f87..7b1fc025aa6d177ee952d0823cc2826511a4c2a0 100644 (file)
@@ -1,5 +1,5 @@
 /* Common core note type descriptions for Linux.
-   Copyright (C) 2007 Red Hat, Inc.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -118,8 +118,8 @@ static const Ebl_Core_Item prstatus_items[] =
     FIELD (signal, INT, info.si_code, 'd'),
     FIELD (signal, INT, info.si_errno, 'd'),
     FIELD (signal, SHORT, cursig, 'd'),
-    FIELD (signal, ULONG, sigpend, 'b'),
-    FIELD (signal, ULONG, sighold, 'b'),
+    FIELD (signal, ULONG, sigpend, 'B'),
+    FIELD (signal, ULONG, sighold, 'B'),
     FIELD (identity, PID_T, pid, 'd', .thread_identifier = true),
     FIELD (identity, PID_T, ppid, 'd'),
     FIELD (identity, PID_T, pgrp, 'd'),
index 02a592fd99704a8b0c580a9e7c588674bcf5f0a6..3060a605538964756d29e45c5f0c802c45b8a393 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of PPC64 specific backend library.
-   Copyright (C) 2004, 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -58,6 +58,7 @@ ppc64_init (elf, machine, eh, ehlen)
   HOOK (eh, bss_plt_p);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
   HOOK (eh, core_note);
   HOOK (eh, auxv_info);
 
index 59e619e196fe2b1e17ac5e3cb276159f633dd635..af0c46aa5e8812e125e84ee265f26e3efffefdf0 100644 (file)
@@ -117,9 +117,14 @@ static const Ebl_Register_Location spe_regs[] =
 #define TYPE_GID_T             ELF_T_WORD
 
 #define PRSTATUS_REGSET_ITEMS                                                \
+  {                                                                          \
+    .name = "nip", .type = ELF_T_ADDR, .format = 'x',                        \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[32]),               \
+    .group = "register"                                                              \
+  },                                                                         \
   {                                                                          \
     .name = "orig_gpr3", .type = TYPE_LONG, .format = 'd',                   \
-    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 34),        \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[34]),               \
     .group = "register"                                                              \
   }
 
index 2e587167d74af1c80c39c6649a3a8c774d5c595e..523c658394c295acd53099866e6f6f3762f92429 100644 (file)
@@ -57,6 +57,7 @@ ppc_init (elf, machine, eh, ehlen)
   HOOK (eh, bss_plt_p);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
   HOOK (eh, core_note);
   HOOK (eh, auxv_info);
   HOOK (eh, check_object_attribute);
diff --git a/backends/ppc_syscall.c b/backends/ppc_syscall.c
new file mode 100644 (file)
index 0000000..23eff81
--- /dev/null
@@ -0,0 +1,50 @@
+/* Linux/PPC system call ABI in DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+int
+ppc_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+                int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = 1;
+  *pc = -1;
+  *callno = 0;
+  args[0] = 3;
+  args[1] = 4;
+  args[2] = 5;
+  args[3] = 6;
+  args[4] = 7;
+  args[5] = 8;
+  return 0;
+}
+
+__typeof (ppc_syscall_abi)
+ppc64_syscall_abi __attribute__ ((alias ("ppc_syscall_abi")));
index 4e9eb55c15dec27ca7c12396463186121f3913fa..a2eaffa5f35b921b6e07fe609d2955f442fadae9 100644 (file)
@@ -53,6 +53,7 @@ x86_64_init (elf, machine, eh, ehlen)
   HOOK (eh, core_note);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
   HOOK (eh, auxv_info);
   HOOK (eh, disasm);
 
diff --git a/backends/x86_64_syscall.c b/backends/x86_64_syscall.c
new file mode 100644 (file)
index 0000000..c3db715
--- /dev/null
@@ -0,0 +1,47 @@
+/* Linux/x86-64 system call ABI in DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+int
+x86_64_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+                   int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = 7;                     /* %rsp */
+  *pc = 16;                    /* %rip */
+  *callno = 0;                 /* %rax */
+  args[0] = 5;                 /* %rdi */
+  args[1] = 4;                 /* %rsi */
+  args[2] = 1;                 /* %rdx */
+  args[3] = 10;                        /* %r10 */
+  args[4] = 8;                 /* %r8 */
+  args[5] = 9;                 /* %r9 */
+  return 0;
+}
index 38f6be73a3393edead1cb0f681996757135efe94..28c6ee3cdf9f3a2d61a4dae6202b00e97785c001 100644 (file)
@@ -1,3 +1,17 @@
+2008-08-03  Roland McGrath  <roland@redhat.com>
+
+       * linux-kernel-modules.c: Include <fts.h> before <config.h>.
+
+2008-07-17  Roland McGrath  <roland@redhat.com>
+
+       * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Set errno to
+       zero if the failure was only ENOENT.
+
+2008-06-03  Roland McGrath  <roland@redhat.com>
+
+       * dwfl_module_addrsym.c (dwfl_module_addrsym): Exclude undefined
+       symbols.
+
 2008-05-22  Petr Machata  <pmachata@redhat.com>
 
        * dwfl_module_getdwarf.c (open_elf): Bias of ET_EXEC files is always 0.
index a6e38ce7726b26f1a79608e981aa625693f8a31b..1a226dfd0ec92ef267c154a955536937666d44f5 100644 (file)
@@ -119,6 +119,13 @@ __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name)
       free (name);
     }
 
+  /* If we simply found nothing, clear errno.  If we had some other error
+     with the file, report that.  Possibly this should treat other errors
+     like ENOENT too.  But ignoring all errors could mask some that should
+     be reported.  */
+  if (fd < 0 && errno == ENOENT)
+    errno = 0;
+
   return fd;
 }
 
index f16de116c93d495e770cb70531f9c9aaba786c70..bc1d556e7a9419b9d9731335d696e4905239a5e2 100644 (file)
@@ -1,5 +1,5 @@
 /* Find debugging and symbol information for a module in libdwfl.
-   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -117,6 +117,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
       GElf_Word shndx;
       const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx);
       if (name != NULL
+         && sym.st_shndx != SHN_UNDEF
          && sym.st_value <= addr
          && (sym.st_size == 0 || addr - sym.st_value < sym.st_size))
        {
index 2cfe6bc8a35cdefdcb42099e0a37db61d7c4ca7b..5bbb384adeb920b1e265e5541d33805472ad0bca 100644 (file)
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
+/* We include this before config.h because it can't handle _FILE_OFFSET_BITS.
+   Everything we need here is fine if its declarations just come first.  */
+
+#include <fts.h>
+
 #include <config.h>
-#undef _FILE_OFFSET_BITS       /* Doesn't jibe with fts.  */
 
 #include "libdwflP.h"
 #include <inttypes.h>
@@ -60,7 +64,6 @@
 #include <sys/utsname.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <fts.h>
 
 
 #define KERNEL_MODNAME "kernel"
index 9838727a81563b2c533ad4c61963cf781f800fe7..57ac2c8c9c34dbd6776e9eed18a7652baa4a5825 100644 (file)
@@ -1,3 +1,19 @@
+2008-07-28  Roland McGrath  <roland@redhat.com>
+
+       * eblauxvinfo.c (AUXV_TYPES): Add EXECFN.
+
+       * eblauxvinfo.c (ebl_auxv_info): Handle missing elements of standard
+       table.
+
+2008-07-04  Roland McGrath  <roland@redhat.com>
+
+       * libebl.h: Declare ebl_syscall_abi.
+       * ebl_syscall_abi.c: New file.
+       * Makefile.am (gen_SOURCES): Add it.
+       * ebl-hooks.h: New hook syscall_abi.
+       * eblopenbackend.c (default_syscall_abi): New function.
+       (fill_defaults): Use it.
+
 2008-03-31  Roland McGrath  <roland@redhat.com>
 
        * ebldynamictagname.c (ebl_dynamic_tag_name): Use hex for unknown tag.
index 0d06a85973c99b9711bbe57135cb17ceb984bf4c..c4e4a076259f1294527082a372a0f002c00835c1 100644 (file)
@@ -59,7 +59,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
              ebl_check_special_symbol.c eblbsspltp.c eblretval.c \
              eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \
              eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \
-             ebl_check_special_section.c
+             ebl_check_special_section.c ebl_syscall_abi.c
 
 libebl_a_SOURCES = $(gen_SOURCES)
 
index 9f6c8d2cd6649a7d0abcb6842cfeb81091583b8f..2db1e208714b049d89a29b81592dbf65669baf97 100644 (file)
@@ -158,6 +158,10 @@ ssize_t EBLHOOK(register_info) (Ebl *ebl,
                                const char **prefix, const char **setname,
                                int *bits, int *type);
 
+/* Return system call ABI registers.  */
+int EBLHOOK(syscall_abi) (Ebl *ebl, int *sp, int *pc,
+                         int *callno, int args[6]);
+
 /* Disassembler function.  */
 int EBLHOOK(disasm) (const uint8_t **startp, const uint8_t *end,
                     GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb,
diff --git a/libebl/ebl_syscall_abi.c b/libebl/ebl_syscall_abi.c
new file mode 100644 (file)
index 0000000..2d9a26b
--- /dev/null
@@ -0,0 +1,66 @@
+/* Return system call ABI mapped to DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_syscall_abi (ebl, sp, pc, callno, args)
+     Ebl *ebl;
+     int *sp;
+     int *pc;
+     int *callno;
+     int args[6];
+{
+  return ebl != NULL ? ebl->syscall_abi (ebl, sp, pc, callno, args) : -1;
+}
index 54583f9fb14285a3550b11adfa6cefb62fb503ea..af65c47b9bf0916b8f7f6ae3716d65ff2d9e99ed 100644 (file)
@@ -1,5 +1,5 @@
 /* Describe known auxv types.
-   Copyright (C) 2007 Red Hat, Inc.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -63,6 +63,7 @@
   TYPE (NULL, "")                                                            \
   TYPE (IGNORE, "")                                                          \
   TYPE (EXECFD, "d")                                                         \
+  TYPE (EXECFN, "s")                                                         \
   TYPE (PHDR, "p")                                                           \
   TYPE (PHENT, "u")                                                          \
   TYPE (PHNUM, "u")                                                          \
@@ -110,7 +111,7 @@ ebl_auxv_info (ebl, a_type, name, format)
      const char **format;
 {
   int result = ebl->auxv_info (a_type, name, format);
-  if (result == 0 && a_type < nauxv_types)
+  if (result == 0 && a_type < nauxv_types && auxv_types[a_type].name != NULL)
     {
       /* The machine specific function did not know this type.  */
       *name = auxv_types[a_type].name;
index 672e834b1587d58bb6b20096a310ce72c823f0bb..8cf421893fcd051c67bfe630aabea6b18bacc732 100644 (file)
@@ -212,6 +212,8 @@ static ssize_t default_register_info (Ebl *ebl,
                                      const char **prefix,
                                      const char **setname,
                                      int *bits, int *type);
+static int default_syscall_abi (Ebl *ebl, int *sp, int *pc,
+                               int *callno, int args[6]);
 static bool default_check_object_attribute (Ebl *ebl, const char *vendor,
                                            int tag, uint64_t value,
                                            const char **tag_name,
@@ -253,6 +255,7 @@ fill_defaults (Ebl *result)
   result->bss_plt_p = default_bss_plt_p;
   result->return_value_location = default_return_value_location;
   result->register_info = default_register_info;
+  result->syscall_abi = default_syscall_abi;
   result->check_object_attribute = default_check_object_attribute;
   result->disasm = NULL;
   result->destr = default_destr;
@@ -718,6 +721,20 @@ default_register_info (Ebl *ebl __attribute__ ((unused)),
   return snprintf (name, namelen, "reg%d", regno);
 }
 
+static int
+default_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+                    int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = *pc = *callno = -1;
+  args[0] = -1;
+  args[1] = -1;
+  args[2] = -1;
+  args[3] = -1;
+  args[4] = -1;
+  args[5] = -1;
+  return -1;
+}
+
 static bool
 default_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
                                const char *vendor  __attribute__ ((unused)),
index 118ae7e79368e8d852f9a59470ae5701e9649b6a..50258690c5d2f0baaba686b2bd32b8f5f3558e55 100644 (file)
@@ -248,6 +248,13 @@ extern ssize_t ebl_register_info (Ebl *ebl,
                                  const char **prefix, const char **setname,
                                  int *bits, int *type);
 
+/* Fill in the DWARF register numbers for the registers used in system calls.
+   The SP and PC are what kernel reports call the user stack pointer and PC.
+   The CALLNO and ARGS are the system call number and incoming arguments.
+   Each of these is filled with the DWARF register number corresponding,
+   or -1 if there is none.  Returns zero when the information is available.  */
+extern int ebl_syscall_abi (Ebl *ebl, int *sp, int *pc,
+                           int *callno, int args[6]);
 
 /* ELF string table handling.  */
 struct Ebl_Strtab;
index f646c06ba48f3c0bf020e43d664609ef26611d8a..8e07b9ded886d4023d3e7ae0c1e40f608740000f 100644 (file)
@@ -1,3 +1,7 @@
+2008-07-28  Roland McGrath  <roland@redhat.com>
+
+       * elf.h: Update from glibc.
+
 2008-03-31  Roland McGrath  <roland@redhat.com>
 
        * elf32_offscn.c: Make sure shdrs have been read in.
index 928e9ec976764e10ca806cdf85958ed2742e00f7..a4134462ac3dc94052375ae0eca33e1fe42527b5 100644 (file)
@@ -970,6 +970,8 @@ typedef struct
 
 #define        AT_SECURE       23              /* Boolean, was exec setuid-like?  */
 
+#define AT_EXECFN      31              /* Filename of executable.  */
+
 /* Pointer to the global system page used for system calls and other
    nice things.  */
 #define AT_SYSINFO     32
@@ -1159,8 +1161,17 @@ typedef struct
 #define R_386_TLS_DTPMOD32 35          /* ID of module containing symbol */
 #define R_386_TLS_DTPOFF32 36          /* Offset in TLS block */
 #define R_386_TLS_TPOFF32  37          /* Negated offset in static TLS block */
+/* 38? */
+#define R_386_TLS_GOTDESC  39          /* GOT offset for TLS descriptor.  */
+#define R_386_TLS_DESC_CALL 40         /* Marker of call through TLS
+                                          descriptor for
+                                          relaxation.  */
+#define R_386_TLS_DESC     41          /* TLS descriptor containing
+                                          pointer to code and to
+                                          argument, returning the TLS
+                                          offset for the symbol.  */
 /* Keep this the last entry.  */
-#define R_386_NUM         38
+#define R_386_NUM         42
 
 /* SUN SPARC specific definitions.  */
 
@@ -2557,8 +2568,17 @@ typedef Elf32_Addr Elf32_Conflict;
 #define R_X86_64_GOTTPOFF      22      /* 32 bit signed PC relative offset
                                           to GOT entry for IE symbol */
 #define R_X86_64_TPOFF32       23      /* Offset in initial TLS block */
+#define R_X86_64_PC64          24      /* PC relative 64 bit */
+#define R_X86_64_GOTOFF64      25      /* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32       26      /* 32 bit signed pc relative
+                                          offset to GOT */
+/* 27 .. 33 */
+#define R_X86_64_GOTPC32_TLSDESC 34    /* GOT offset for TLS descriptor.  */
+#define R_X86_64_TLSDESC_CALL   35     /* Marker for call through TLS
+                                          descriptor.  */
+#define R_X86_64_TLSDESC        36     /* TLS descriptor.  */
 
-#define R_X86_64_NUM           24
+#define R_X86_64_NUM           37
 
 
 /* AM33 relocations.  */
index 94444c581cbe1f4830e9496c30007c1b090b7b63..4ef23a22f6e9560ca610628535238a6137568602 100644 (file)
@@ -1,3 +1,30 @@
+2008-08-07  Roland McGrath  <roland@redhat.com>
+
+       * addr2line.c (main): Pass string to handle_address.
+       (see_one_module): New function, subroutine of handle_address.
+       (find_symbol): Likewise.
+       (handle_address): Take string argument rather than address.
+       Convert plain number, or handle strings like "(section)+offset"
+       or "symbol+offset".
+
+2008-08-01  Roland McGrath  <roland@redhat.com>
+
+       * readelf.c (handle_core_item): Handle 'B' type for 1-origin bitset.
+       For 'b' and 'B', print <x-y,z> or ~<x,y-z> rather than 1/0 string.
+
+       * readelf.c (convert): Take new argument SIZE.
+       (handle_core_register, handle_core_item): Update callers.
+       (handle_core_item): Take new arg REPEATED_SIZE.
+       (handle_core_items): Special case for a singleton item,
+       let handle_core_item handle repeats if it wants to.
+
+       * readelf.c (handle_core_items): Give abridged output
+       for identical groups repeated more than twice.
+
+2008-07-04  Roland McGrath  <roland@redhat.com>
+
+       * readelf.c (handle_core_items): Handle ELF_T_ADDR.
+
 2008-04-10  Roland McGrath  <roland@redhat.com>
 
        * strip.c (handle_elf): Don't keep sections that kept symbol tables
index 4b1d13e7bcc357d0c557ebcdf0bfb11873b253d7..0d11e188c1ab645326cb51afa65cee83885aa408 100644 (file)
@@ -1,5 +1,5 @@
 /* Locate source files and line information for given addresses
-   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2005.
 
@@ -96,7 +96,7 @@ static const struct argp argp =
 
 
 /* Handle ADDR.  */
-static void handle_address (GElf_Addr addr, Dwfl *dwfl);
+static int handle_address (const char *addr, Dwfl *dwfl);
 
 
 /* True if only base names of files should be shown.  */
@@ -154,12 +154,7 @@ main (int argc, char *argv[])
          if (getline (&buf, &len, stdin) < 0)
            break;
 
-         char *endp;
-         uintmax_t addr = strtoumax (buf, &endp, 0);
-         if (endp != buf)
-           handle_address (addr, dwfl);
-         else
-           result = 1;
+         result = handle_address (buf, dwfl);
        }
 
       free (buf);
@@ -167,14 +162,7 @@ main (int argc, char *argv[])
   else
     {
       do
-       {
-         char *endp;
-         uintmax_t addr = strtoumax (argv[remaining], &endp, 0);
-         if (endp != argv[remaining])
-           handle_address (addr, dwfl);
-         else
-           result = 1;
-       }
+       result = handle_address (argv[remaining], dwfl);
       while (++remaining < argc);
     }
 
@@ -328,9 +316,131 @@ print_addrsym (Dwfl_Module *mod, GElf_Addr addr)
     printf ("%s+%#" PRIx64 "\n", name, addr - s.st_value);
 }
 
-static void
-handle_address (GElf_Addr addr, Dwfl *dwfl)
+static int
+see_one_module (Dwfl_Module *mod,
+               void **userdata __attribute__ ((unused)),
+               const char *name __attribute__ ((unused)),
+               Dwarf_Addr start __attribute__ ((unused)),
+               void *arg)
+{
+  Dwfl_Module **result = arg;
+  if (*result != NULL)
+    return DWARF_CB_ABORT;
+  *result = mod;
+  return DWARF_CB_OK;
+}
+
+static int
+find_symbol (Dwfl_Module *mod,
+            void **userdata __attribute__ ((unused)),
+            const char *name __attribute__ ((unused)),
+            Dwarf_Addr start __attribute__ ((unused)),
+            void *arg)
+{
+  const char *looking_for = ((void **) arg)[0];
+  GElf_Sym *symbol = ((void **) arg)[1];
+
+  int n = dwfl_module_getsymtab (mod);
+  for (int i = 1; i < n; ++i)
+    {
+      const char *symbol_name = dwfl_module_getsym (mod, i, symbol, NULL);
+      if (symbol_name == NULL)
+       continue;
+      switch (GELF_ST_TYPE (symbol->st_info))
+       {
+       case STT_SECTION:
+       case STT_FILE:
+       case STT_TLS:
+         break;
+       default:
+         if (!strcmp (symbol_name, looking_for))
+           {
+             ((void **) arg)[0] = NULL;
+             return DWARF_CB_ABORT;
+           }
+       }
+    }
+
+  return DWARF_CB_OK;
+}
+
+static int
+handle_address (const char *string, Dwfl *dwfl)
 {
+  char *endp;
+  uintmax_t addr = strtoumax (string, &endp, 0);
+  if (endp == string)
+    {
+      bool parsed = false;
+      int n;
+      char *name = NULL;
+      if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &n) == 2
+         && string[n] == '\0')
+       {
+         /* It was (section)+offset.  This makes sense if there is
+            only one module to look in for a section.  */
+         Dwfl_Module *mod = NULL;
+         if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0
+             || mod == NULL)
+           error (EXIT_FAILURE, 0, gettext ("Section syntax requires"
+                                            " exactly one module"));
+
+         int nscn = dwfl_module_relocations (mod);
+         for (int i = 0; i < nscn; ++i)
+           {
+             GElf_Word shndx;
+             const char *scn = dwfl_module_relocation_info (mod, i, &shndx);
+             if (unlikely (scn == NULL))
+               break;
+             if (!strcmp (scn, name))
+               {
+                 /* Found the section.  */
+                 GElf_Shdr shdr_mem;
+                 GElf_Addr shdr_bias;
+                 GElf_Shdr *shdr = gelf_getshdr
+                   (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx),
+                    &shdr_mem);
+                 if (unlikely (shdr == NULL))
+                   break;
+
+                 if (addr >= shdr->sh_size)
+                   error (0, 0,
+                          gettext ("offset %#" PRIxMAX " lies outside"
+                                   " section '%s'"),
+                          addr, scn);
+
+                 addr += shdr->sh_addr + shdr_bias;
+                 parsed = true;
+                 break;
+               }
+           }
+       }
+      else if (sscanf (string, "%m[^-+]%" PRIiMAX "%n", &name, &addr, &n) == 2
+              && string[n] == '\0')
+       {
+         /* It was symbol+offset.  */
+         GElf_Sym sym;
+         void *arg[2] = { name, &sym };
+         (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0);
+         if (arg[0] != NULL)
+           error (0, 0, gettext ("cannot find symbol '%s'"), name);
+         else
+           {
+             if (sym.st_size != 0 && addr >= sym.st_size)
+               error (0, 0,
+                      gettext ("offset %#" PRIxMAX " lies outside"
+                               " contents of '%s'"),
+                      addr, name);
+             addr += sym.st_value;
+             parsed = true;
+           }
+       }
+
+      free (name);
+      if (!parsed)
+       return 1;
+    }
+
   Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr);
 
   if (show_functions)
@@ -372,6 +482,8 @@ handle_address (GElf_Addr addr, Dwfl *dwfl)
     }
   else
     puts ("??:0");
+
+  return 0;
 }
 
 
index 96b5d436c273dd5640cf21d0557b25eef20eeb36..7b599ec8a34c19c1f4902d069edeb4ac2f9f841a 100644 (file)
@@ -5389,13 +5389,13 @@ print_core_item (unsigned int colno, char sep, unsigned int wrap,
 
 static const void *
 convert (Elf *core, Elf_Type type, uint_fast16_t count,
-        void *value, const void *data)
+        void *value, const void *data, size_t size)
 {
   Elf_Data valuedata =
     {
       .d_type = type,
       .d_buf = value,
-      .d_size = gelf_fsize (core, type, count, EV_CURRENT),
+      .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
       .d_version = EV_CURRENT,
     };
   Elf_Data indata =
@@ -5420,7 +5420,7 @@ typedef uint8_t GElf_Byte;
 
 static unsigned int
 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
-                 unsigned int colno)
+                 unsigned int colno, size_t *repeated_size)
 {
   uint_fast16_t count = item->count ?: 1;
 
@@ -5436,13 +5436,33 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
   union { TYPES; } value;
 #undef DO_TYPE
 
-  desc = convert (core, item->type, count, &value, desc + item->offset);
+  void *data = &value;
+  size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
+  size_t convsize = size;
+  if (repeated_size != NULL)
+    {
+      if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
+       {
+         data = alloca (*repeated_size);
+         count *= *repeated_size / size;
+         convsize = count * size;
+         *repeated_size -= convsize;
+       }
+      else
+       *repeated_size -= size;
+    }
+
+  desc = convert (core, item->type, count, data, desc + item->offset, convsize);
+
+  Elf_Type type = item->type;
+  if (type == ELF_T_ADDR)
+    type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
 
   switch (item->format)
     {
     case 'd':
       assert (count == 1);
-      switch (item->type)
+      switch (type)
        {
 #define DO_TYPE(NAME, Name, hex, dec, max)                                   \
          case ELF_T_##NAME:                                                  \
@@ -5458,7 +5478,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
 
     case 'x':
       assert (count == 1);
-      switch (item->type)
+      switch (type)
        {
 #define DO_TYPE(NAME, Name, hex, dec, max)                                   \
          case ELF_T_##NAME:                                                  \
@@ -5473,30 +5493,59 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
       break;
 
     case 'b':
-      assert (count == 1);
-      Dwarf_Word bits = 0;
-      Dwarf_Word bit = 0;
-      switch (item->type)
-       {
-#define DO_TYPE(NAME, Name, hex, dec, max)                             \
-         case ELF_T_##NAME:                                                  \
-           bits = value.Name[0];                                             \
-           bit = (Dwarf_Word) 1 << ((sizeof value.Name[0] * 8) - 1);         \
-           break
-         TYPES;
-#undef DO_TYPE
-       default:
-         abort ();
-       }
-      char printed[sizeof (Dwarf_Word) * 8 + 1];
-      int i = 0;
-      while (bit != 0)
-       {
-         printed[i++] = (bits & bit) ? '1' : '0';
-         bit >>= 1;
-       }
-      colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
-                              sizeof printed - 1, "%.*s", i, printed);
+    case 'B':
+      assert (size % sizeof (unsigned int) == 0);
+      unsigned int nbits = count * size * 8;
+      unsigned int pop = 0;
+      for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
+       pop += __builtin_popcount (*i);
+      bool negate = pop > nbits / 2;
+      const unsigned int bias = item->format == 'b';
+
+      {
+       char printed[(negate ? nbits - pop : pop) * 16];
+       char *p = printed;
+       *p = '\0';
+
+       if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
+         {
+           assert (size == sizeof (unsigned int) * 2);
+           for (unsigned int *i = data;
+                (void *) i < data + count * size; i += 2)
+             {
+               unsigned int w = i[1];
+               i[1] = i[0];
+               i[0] = w;
+             }
+         }
+
+       unsigned int lastbit = 0;
+       for (const unsigned int *i = data;
+            (void *) i < data + count * size; ++i)
+         {
+           unsigned int bit = ((void *) i - data) * 8;
+           unsigned int w = negate ? ~*i : *i;
+           while (w != 0)
+             {
+               int n = ffs (w);
+               w >>= n;
+               bit += n;
+
+               if (lastbit + 1 != bit)
+                 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
+               else if (lastbit == 0)
+                 p += sprintf (p, "%u", bit - bias);
+
+               lastbit = bit;
+             }
+         }
+       if (lastbit > 0 && lastbit + 1 != nbits)
+         p += sprintf (p, "-%u", nbits - bias);
+
+       colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
+                                4 + nbits * 4,
+                                negate ? "~<%s>" : "<%s>", printed);
+      }
       break;
 
     case 'T':
@@ -5505,7 +5554,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
       Dwarf_Word sec;
       Dwarf_Word usec;
       size_t maxfmt = 7;
-      switch (item->type)
+      switch (type)
        {
 #define DO_TYPE(NAME, Name, hex, dec, max)                                   \
          case ELF_T_##NAME:                                                  \
@@ -5615,6 +5664,17 @@ handle_core_items (Elf *core, const void *desc, size_t descsz,
   /* Write out all the groups.  */
   unsigned int colno = 0;
 
+  const void *last = desc;
+  if (nitems == 1)
+    {
+      size_t size = descsz;
+      colno = handle_core_item (core, sorted_items[0], desc, colno, &size);
+      if (size == 0)
+       return colno;
+      desc += descsz - size;
+      descsz = size;
+    }
+
   do
     {
       for (size_t i = 0; i < ngroups; ++i)
@@ -5624,7 +5684,7 @@ handle_core_items (Elf *core, const void *desc, size_t descsz,
                && ((*item)->group == groups[i][0]->group
                    || !strcmp ((*item)->group, groups[i][0]->group)));
               ++item)
-           colno = handle_core_item (core, *item, desc, colno);
+           colno = handle_core_item (core, *item, desc, colno, NULL);
 
          /* Force a line break at the end of the group.  */
          colno = ITEM_WRAP_COLUMN;
@@ -5639,8 +5699,27 @@ handle_core_items (Elf *core, const void *desc, size_t descsz,
       const Ebl_Core_Item *item = &items[nitems - 1];
       size_t eltsz = item->offset + gelf_fsize (core, item->type,
                                                item->count ?: 1, EV_CURRENT);
-      descsz -= eltsz;
-      desc += eltsz;
+
+      int reps = -1;
+      do
+       {
+         ++reps;
+         desc += eltsz;
+         descsz -= eltsz;
+       }
+      while (descsz >= eltsz && !memcmp (desc, last, eltsz));
+
+      if (reps == 1)
+       {
+         /* For just one repeat, print it unabridged twice.  */
+         desc -= eltsz;
+         descsz += eltsz;
+       }
+      else if (reps > 1)
+       printf (gettext ("\n%*s... <repeats %u more times> ..."),
+               ITEM_INDENT, "", reps);
+
+      last = desc;
     }
   while (descsz > 0);
 
@@ -5702,7 +5781,7 @@ handle_core_register (Ebl *ebl, Elf *core, int maxregname,
            {
 #define BITS(bits, xtype, sfmt, ufmt, max)                                   \
            case bits:                                                        \
-             desc = convert (core, ELF_T_##xtype, 1, &value, desc);          \
+             desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);       \
              if (type == DW_ATE_signed)                                      \
                colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,    \
                                         maxregname, name,                    \
@@ -5717,7 +5796,7 @@ handle_core_register (Ebl *ebl, Elf *core, int maxregname,
 
            case 128:
              assert (type == DW_ATE_unsigned);
-             desc = convert (core, ELF_T_XWORD, 2, &value, desc);
+             desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
              int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
              colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,
                                       maxregname, name,