summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2005-09-03 23:57:29 +0000
committerDmitry V. Levin <ldv@altlinux.org>2005-09-03 23:57:29 +0000
commit10317c17ff72b7cf3bba318881d3224a7909341b (patch)
treed36d8ec9817dcf4553130fb2702205d61c8a4eb6
parent3e89d2075378ae2a7d49f8235c0426fdb48a6951 (diff)
downloadelfutils-10317c17ff72b7cf3bba318881d3224a7909341b.tar.gz
0.114-alt10.114-alt1
- Updated to 0.114.
-rw-r--r--elfutils-0.114-alt-makefile.patch44
-rw-r--r--elfutils-0.114-rh-robustify.patch (renamed from elfutils-0.108-rh-robustify.patch)1949
-rw-r--r--elfutils.spec18
-rw-r--r--elfutils/ChangeLog25
-rw-r--r--elfutils/Makefile.am2
-rw-r--r--elfutils/Makefile.in10
-rw-r--r--elfutils/NEWS60
-rw-r--r--elfutils/THANKS1
-rw-r--r--elfutils/TODO14
-rw-r--r--elfutils/aclocal.m44
-rw-r--r--elfutils/config.h.in10
-rw-r--r--elfutils/config/ChangeLog12
-rw-r--r--elfutils/config/Makefile.am2
-rw-r--r--elfutils/config/Makefile.in10
-rw-r--r--[-rwxr-xr-x]elfutils/config/depcomp0
-rw-r--r--elfutils/config/elfutils.spec.in69
-rw-r--r--[-rwxr-xr-x]elfutils/config/install-sh0
-rw-r--r--[-rwxr-xr-x]elfutils/config/missing0
-rw-r--r--[-rwxr-xr-x]elfutils/config/mkinstalldirs2
-rwxr-xr-xelfutils/configure106
-rw-r--r--elfutils/configure.ac36
-rw-r--r--elfutils/elfutils.spec71
-rw-r--r--elfutils/lib/ChangeLog4
-rw-r--r--elfutils/lib/Makefile.am2
-rw-r--r--elfutils/lib/Makefile.in12
-rw-r--r--elfutils/libasm/ChangeLog18
-rw-r--r--elfutils/libasm/Makefile.am2
-rw-r--r--elfutils/libasm/Makefile.in18
-rw-r--r--elfutils/libasm/asm_abort.c5
-rw-r--r--elfutils/libasm/asm_addint8.c21
-rw-r--r--elfutils/libasm/asm_addsleb128.c4
-rw-r--r--elfutils/libasm/asm_adduleb128.c4
-rw-r--r--elfutils/libasm/asm_align.c29
-rw-r--r--elfutils/libasm/asm_begin.c86
-rw-r--r--elfutils/libasm/asm_end.c7
-rw-r--r--elfutils/libasm/asm_error.c5
-rw-r--r--elfutils/libasm/asm_newscn.c5
-rw-r--r--elfutils/libasm/libasm.h7
-rw-r--r--elfutils/libasm/libasmP.h4
-rw-r--r--elfutils/libcpu/Makefile.in10
-rw-r--r--elfutils/libdw/ChangeLog195
-rw-r--r--elfutils/libdw/Makefile.am28
-rw-r--r--elfutils/libdw/Makefile.in82
-rw-r--r--elfutils/libdw/dwarf.h2
-rw-r--r--elfutils/libdw/dwarf_attr_integrate.c45
-rw-r--r--elfutils/libdw/dwarf_begin_elf.c3
-rw-r--r--elfutils/libdw/dwarf_child.c8
-rw-r--r--elfutils/libdw/dwarf_end.c1
-rw-r--r--elfutils/libdw/dwarf_error.c5
-rw-r--r--elfutils/libdw/dwarf_formblock.c8
-rw-r--r--elfutils/libdw/dwarf_formref.c6
-rw-r--r--elfutils/libdw/dwarf_formref_die.c28
-rw-r--r--elfutils/libdw/dwarf_formsdata.c9
-rw-r--r--elfutils/libdw/dwarf_formudata.c9
-rw-r--r--elfutils/libdw/dwarf_func_die.c (renamed from elfutils/libebl/mips_destr.c)16
-rw-r--r--elfutils/libdw/dwarf_func_inline.c72
-rw-r--r--elfutils/libdw/dwarf_getabbrev.c13
-rw-r--r--elfutils/libdw/dwarf_getabbrevattr.c6
-rw-r--r--elfutils/libdw/dwarf_getarange_addr.c17
-rw-r--r--elfutils/libdw/dwarf_getaranges.c66
-rw-r--r--elfutils/libdw/dwarf_getattrs.c8
-rw-r--r--elfutils/libdw/dwarf_getloclist.c216
-rw-r--r--elfutils/libdw/dwarf_getmacros.c5
-rw-r--r--elfutils/libdw/dwarf_getscopes.c343
-rw-r--r--elfutils/libdw/dwarf_getscopevar.c147
-rw-r--r--elfutils/libdw/dwarf_getsrcfiles.c1
-rw-r--r--elfutils/libdw/dwarf_getsrclines.c16
-rw-r--r--elfutils/libdw/dwarf_hasattr.c3
-rw-r--r--elfutils/libdw/dwarf_hasattr_integrate.c42
-rw-r--r--elfutils/libdw/dwarf_haschildren.c5
-rw-r--r--elfutils/libdw/dwarf_haspc.c105
-rw-r--r--elfutils/libdw/dwarf_tag.c2
-rw-r--r--elfutils/libdw/libdw.h68
-rw-r--r--elfutils/libdw/libdw.map59
-rw-r--r--elfutils/libdw/libdwP.h98
-rw-r--r--elfutils/libdw/libdw_form.c6
-rw-r--r--elfutils/libdw/libdw_visit_scopes.c104
-rw-r--r--elfutils/libdw/memory-access.c35
-rw-r--r--elfutils/libdw/memory-access.h142
-rw-r--r--elfutils/libdwfl/ChangeLog189
-rw-r--r--elfutils/libdwfl/Makefile.am84
-rw-r--r--elfutils/libdwfl/Makefile.in542
-rw-r--r--elfutils/libdwfl/argp-std.c210
-rw-r--r--elfutils/libdwfl/cu.c275
-rw-r--r--elfutils/libdwfl/derelocate.c231
-rw-r--r--elfutils/libdwfl/dwfl_addrdie.c21
-rw-r--r--elfutils/libdwfl/dwfl_addrdwarf.c22
-rw-r--r--elfutils/libdwfl/dwfl_addrmodule.c38
-rw-r--r--elfutils/libdwfl/dwfl_begin.c36
-rw-r--r--elfutils/libdwfl/dwfl_cumodule.c21
-rw-r--r--elfutils/libdwfl/dwfl_end.c26
-rw-r--r--elfutils/libdwfl/dwfl_error.c222
-rw-r--r--elfutils/libdwfl/dwfl_getdwarf.c40
-rw-r--r--elfutils/libdwfl/dwfl_getmodules.c37
-rw-r--r--elfutils/libdwfl/dwfl_getsrc.c21
-rw-r--r--elfutils/libdwfl/dwfl_getsrclines.c33
-rw-r--r--elfutils/libdwfl/dwfl_lineinfo.c40
-rw-r--r--elfutils/libdwfl/dwfl_linemodule.c23
-rw-r--r--elfutils/libdwfl/dwfl_module.c190
-rw-r--r--elfutils/libdwfl/dwfl_module_addrdie.c30
-rw-r--r--elfutils/libdwfl/dwfl_module_getdwarf.c496
-rw-r--r--elfutils/libdwfl/dwfl_module_getsrc.c60
-rw-r--r--elfutils/libdwfl/dwfl_module_getsrc_file.c152
-rw-r--r--elfutils/libdwfl/dwfl_module_info.c44
-rw-r--r--elfutils/libdwfl/dwfl_module_nextcu.c29
-rw-r--r--elfutils/libdwfl/dwfl_nextcu.c52
-rw-r--r--elfutils/libdwfl/dwfl_onesrcline.c41
-rw-r--r--elfutils/libdwfl/dwfl_report_elf.c171
-rw-r--r--elfutils/libdwfl/dwfl_validate_address.c46
-rw-r--r--elfutils/libdwfl/elf-from-memory.c328
-rw-r--r--elfutils/libdwfl/find-debuginfo.c165
-rw-r--r--elfutils/libdwfl/libdwfl.h335
-rw-r--r--elfutils/libdwfl/libdwflP.h254
-rw-r--r--elfutils/libdwfl/libdwfl_crc32.c23
-rw-r--r--elfutils/libdwfl/libdwfl_crc32_file.c24
-rw-r--r--elfutils/libdwfl/lines.c37
-rw-r--r--elfutils/libdwfl/linux-kernel-modules.c442
-rw-r--r--elfutils/libdwfl/linux-proc-maps.c285
-rw-r--r--elfutils/libdwfl/offline.c78
-rw-r--r--elfutils/libdwfl/relocate.c294
-rw-r--r--elfutils/libebl/ChangeLog204
-rw-r--r--elfutils/libebl/Makefile.am56
-rw-r--r--elfutils/libebl/Makefile.in162
-rw-r--r--elfutils/libebl/alpha_init.c9
-rw-r--r--elfutils/libebl/alpha_symbol.c30
-rw-r--r--elfutils/libebl/arm_init.c7
-rw-r--r--elfutils/libebl/arm_symbol.c7
-rw-r--r--elfutils/libebl/ebl_check_special_symbol.c34
-rw-r--r--elfutils/libebl/eblbsspltp.c28
-rw-r--r--elfutils/libebl/eblcopyrelocp.c28
-rw-r--r--elfutils/libebl/eblcorenote.c66
-rw-r--r--elfutils/libebl/eblelfclass.c27
-rw-r--r--elfutils/libebl/eblelfdata.c27
-rw-r--r--elfutils/libebl/eblelfmachine.c27
-rw-r--r--elfutils/libebl/eblopenbackend.c252
-rw-r--r--elfutils/libebl/eblsectionstripp.c52
-rw-r--r--elfutils/libebl/i386_corenote.c103
-rw-r--r--elfutils/libebl/i386_init.c9
-rw-r--r--elfutils/libebl/i386_symbol.c18
-rw-r--r--elfutils/libebl/ia64_init.c8
-rw-r--r--elfutils/libebl/ia64_symbol.c14
-rw-r--r--elfutils/libebl/libebl.h115
-rw-r--r--elfutils/libebl/libeblP.h105
-rw-r--r--elfutils/libebl/libebl_alpha.h14
-rw-r--r--elfutils/libebl/libebl_alpha.map4
-rw-r--r--elfutils/libebl/libebl_arm.h8
-rw-r--r--elfutils/libebl/libebl_arm.map4
-rw-r--r--elfutils/libebl/libebl_i386.h10
-rw-r--r--elfutils/libebl/libebl_i386.map5
-rw-r--r--elfutils/libebl/libebl_ia64.h12
-rw-r--r--elfutils/libebl/libebl_ia64.map4
-rw-r--r--elfutils/libebl/libebl_mips.h42
-rw-r--r--elfutils/libebl/libebl_mips.map14
-rw-r--r--elfutils/libebl/libebl_ppc.h22
-rw-r--r--elfutils/libebl/libebl_ppc.map4
-rw-r--r--elfutils/libebl/libebl_ppc64.h19
-rw-r--r--elfutils/libebl/libebl_ppc64.map4
-rw-r--r--elfutils/libebl/libebl_sh.h8
-rw-r--r--elfutils/libebl/libebl_sh.map3
-rw-r--r--elfutils/libebl/libebl_sparc.h8
-rw-r--r--elfutils/libebl/libebl_sparc.map4
-rw-r--r--elfutils/libebl/libebl_x86_64.h6
-rw-r--r--elfutils/libebl/libebl_x86_64.map4
-rw-r--r--elfutils/libebl/mips_init.c47
-rw-r--r--elfutils/libebl/mips_symbol.c270
-rw-r--r--elfutils/libebl/ppc64_init.c10
-rw-r--r--elfutils/libebl/ppc64_symbol.c42
-rw-r--r--elfutils/libebl/ppc_init.c11
-rw-r--r--elfutils/libebl/ppc_symbol.c122
-rw-r--r--elfutils/libebl/sh_init.c7
-rw-r--r--elfutils/libebl/sh_symbol.c7
-rw-r--r--elfutils/libebl/sparc_init.c7
-rw-r--r--elfutils/libebl/sparc_symbol.c7
-rw-r--r--elfutils/libebl/x86_64_corenote.c171
-rw-r--r--elfutils/libebl/x86_64_init.c9
-rw-r--r--elfutils/libebl/x86_64_symbol.c7
-rw-r--r--elfutils/libelf-po/libelf.pot6
-rw-r--r--elfutils/libelf/ChangeLog68
-rw-r--r--elfutils/libelf/Makefile.am9
-rw-r--r--elfutils/libelf/Makefile.in32
-rw-r--r--elfutils/libelf/elf-knowledge.h33
-rw-r--r--elfutils/libelf/elf.h30
-rw-r--r--elfutils/libelf/elf32_checksum.c4
-rw-r--r--elfutils/libelf/elf32_offscn.c80
-rw-r--r--elfutils/libelf/elf32_updatenull.c51
-rw-r--r--elfutils/libelf/elf64_offscn.c19
-rw-r--r--elfutils/libelf/elf_begin.c127
-rw-r--r--elfutils/libelf/elf_error.c8
-rw-r--r--elfutils/libelf/elf_getaroff.c42
-rw-r--r--elfutils/libelf/elf_getarsym.c33
-rw-r--r--elfutils/libelf/elf_getdata.c3
-rw-r--r--elfutils/libelf/elf_update.c2
-rw-r--r--elfutils/libelf/gelf.h3
-rw-r--r--elfutils/libelf/gelf_offscn.c45
-rw-r--r--elfutils/libelf/libelf.h10
-rw-r--r--elfutils/libelf/libelf.map8
-rw-r--r--elfutils/libelf/libelfP.h5
-rw-r--r--elfutils/m4/Makefile.in8
-rw-r--r--elfutils/po/ChangeLog13
-rw-r--r--elfutils/po/Makefile.in.in3
-rw-r--r--elfutils/po/POTFILES.in2
-rw-r--r--elfutils/po/elfutils.pot1403
-rw-r--r--elfutils/src/ChangeLog214
-rw-r--r--elfutils/src/Makefile.am35
-rw-r--r--elfutils/src/Makefile.in132
-rw-r--r--elfutils/src/addr2line.c250
-rw-r--r--elfutils/src/elfcmp.c624
-rw-r--r--elfutils/src/elflint.c1609
-rw-r--r--elfutils/src/nm.c9
-rw-r--r--elfutils/src/objdump.c725
-rw-r--r--elfutils/src/ranlib.c503
-rw-r--r--elfutils/src/readelf.c491
-rw-r--r--elfutils/src/strip.c108
-rw-r--r--[-rwxr-xr-x]elfutils/src/ylwrap0
-rw-r--r--elfutils/tests/ChangeLog109
-rw-r--r--elfutils/tests/Makefile.am56
-rw-r--r--elfutils/tests/Makefile.in245
-rw-r--r--elfutils/tests/addrscopes.c194
-rw-r--r--elfutils/tests/asm-tst1.c13
-rw-r--r--elfutils/tests/asm-tst2.c13
-rw-r--r--elfutils/tests/asm-tst3.c13
-rw-r--r--elfutils/tests/asm-tst4.c13
-rw-r--r--elfutils/tests/asm-tst5.c13
-rw-r--r--elfutils/tests/asm-tst6.c13
-rw-r--r--elfutils/tests/asm-tst7.c13
-rw-r--r--elfutils/tests/asm-tst8.c13
-rw-r--r--elfutils/tests/asm-tst9.c13
-rw-r--r--elfutils/tests/dwflmodtest.c248
-rw-r--r--elfutils/tests/get-files.c6
-rw-r--r--elfutils/tests/get-pubnames.c4
-rw-r--r--elfutils/tests/line2addr.c143
-rw-r--r--elfutils/tests/msg_tst.c6
-rw-r--r--elfutils/tests/newfile.c4
-rw-r--r--elfutils/tests/newscn.c4
-rwxr-xr-xelfutils/tests/run-addrscopes.sh31
-rwxr-xr-xelfutils/tests/run-elflint-self.sh47
-rwxr-xr-xelfutils/tests/run-elflint-test.sh28
-rwxr-xr-xelfutils/tests/run-line2addr.sh33
-rwxr-xr-xelfutils/tests/run-ranlib-test.sh34
-rwxr-xr-xelfutils/tests/run-ranlib-test2.sh39
-rwxr-xr-xelfutils/tests/run-ranlib-test3.sh17
-rwxr-xr-xelfutils/tests/run-ranlib-test4.sh18
-rw-r--r--elfutils/tests/scnnames.c8
-rw-r--r--elfutils/tests/showptable.c8
-rw-r--r--elfutils/tests/test-nlist.c4
-rw-r--r--elfutils/tests/testfile18.bz2bin0 -> 1721 bytes
-rw-r--r--elfutils/tests/testfile19.bz2bin0 -> 458 bytes
-rw-r--r--elfutils/tests/testfile19.index.bz2bin0 -> 501 bytes
-rw-r--r--elfutils/tests/testfile20.bz2bin0 -> 502 bytes
-rw-r--r--elfutils/tests/testfile20.index.bz2bin0 -> 523 bytes
-rw-r--r--elfutils/tests/testfile21.bz2bin0 -> 127 bytes
-rw-r--r--elfutils/tests/testfile21.index.bz2bin0 -> 100 bytes
-rw-r--r--elfutils/tests/testfile22.bz2bin0 -> 2555 bytes
-rw-r--r--elfutils/tests/testfile23.bz2bin0 -> 956 bytes
-rw-r--r--elfutils/tests/update1.c4
-rw-r--r--elfutils/tests/update2.c4
-rw-r--r--elfutils/tests/update3.c4
-rw-r--r--elfutils/tests/update4.c4
258 files changed, 17007 insertions, 3862 deletions
diff --git a/elfutils-0.114-alt-makefile.patch b/elfutils-0.114-alt-makefile.patch
new file mode 100644
index 00000000..707b130e
--- /dev/null
+++ b/elfutils-0.114-alt-makefile.patch
@@ -0,0 +1,44 @@
+--- elfutils-0.114/src/Makefile.am.orig 2005-08-15 22:09:07 +0000
++++ elfutils-0.114/src/Makefile.am 2005-09-03 23:12:14 +0000
+@@ -92,7 +92,7 @@ endif
+ ld_LDFLAGS = -rdynamic
+ elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+ findtextrel_LDADD = $(libdw) $(libelf) $(libmudflap)
+-addr2line_LDADD = $(libdw) $(libmudflap)
++addr2line_LDADD = $(libdw) $(libmudflap) -Wl,-rpath-link,../libelf
+ elfcmp_LDADD = $(libebl) $(libelf) $(libmudflap) -ldl
+ objdump_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+ ranlib_LDADD = $(libelf) $(libeu) $(libmudflap)
+--- elfutils-0.114/src/Makefile.in.orig 2005-08-15 22:09:10 +0000
++++ elfutils-0.114/src/Makefile.in 2005-09-03 23:14:33 +0000
+@@ -304,7 +304,7 @@ ld_LDADD = $(libebl) $(libelf) $(libeu)
+ ld_LDFLAGS = -rdynamic
+ elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+ findtextrel_LDADD = $(libdw) $(libelf) $(libmudflap)
+-addr2line_LDADD = $(libdw) $(libmudflap)
++addr2line_LDADD = $(libdw) $(libmudflap) -Wl,-rpath-link,../libelf
+ elfcmp_LDADD = $(libebl) $(libelf) $(libmudflap) -ldl
+ objdump_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+ ranlib_LDADD = $(libelf) $(libeu) $(libmudflap)
+--- elfutils-0.114/tests/Makefile.am.orig 2005-08-25 00:54:05 +0400
++++ elfutils-0.114/tests/Makefile.am 2005-09-04 03:30:01 +0400
+@@ -20,7 +20,7 @@ AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../lib
+ else
+ AM_CFLAGS = -Wall -Wextra -std=gnu99 \
+ $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2)
+-AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../libebl:\$$ORIGIN/../libelf
++AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../libebl:\$$ORIGIN/../libelf,-rpath-link,../libelf
+ endif
+ INCLUDES = -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
+ -I$(top_srcdir)/libdwfl \
+--- elfutils-0.114/tests/Makefile.in.orig 2005-08-25 00:54:11 +0400
++++ elfutils-0.114/tests/Makefile.in 2005-09-04 03:30:47 +0400
+@@ -325,7 +325,7 @@ target_alias = @target_alias@
+ @MUDFLAP_TRUE@AM_CFLAGS = -Wall -Wextra -std=gnu99 -fmudflap\
+ @MUDFLAP_TRUE@ $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2)
+
+-@MUDFLAP_FALSE@AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../libebl:\$$ORIGIN/../libelf
++@MUDFLAP_FALSE@AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../libebl:\$$ORIGIN/../libelf,-rpath-link,../libelf
+ @MUDFLAP_TRUE@AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libebl
+ INCLUDES = -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
+ -I$(top_srcdir)/libdwfl \
diff --git a/elfutils-0.108-rh-robustify.patch b/elfutils-0.114-rh-robustify.patch
index 1e6396e5..f017108b 100644
--- a/elfutils-0.108-rh-robustify.patch
+++ b/elfutils-0.114-rh-robustify.patch
@@ -65,121 +65,427 @@ src/
(check_symtab, is_rel_dyn, check_rela, check_rel, check_dynamic,
check_symtab_shndx, check_hash, check_versym): Robustify.
---- elfutils-0.108/libelf/gelf_getrel.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getrel.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/elf32_getphdr.c
++++ elfutils-0.114/libelf/elf32_getphdr.c
+@@ -80,6 +80,16 @@ elfw2(LIBELFBITS,getphdr) (elf)
+
+ if (elf->map_address != NULL)
+ {
++ /* First see whether the information in the ELF header is
++ valid and it does not ask for too much. */
++ if (unlikely (ehdr->e_phoff >= elf->maximum_size)
++ || unlikely (ehdr->e_phoff + size > elf->maximum_size))
++ {
++ /* Something is wrong. */
++ __libelf_seterrno (ELF_E_INVALID_PHDR);
++ goto out;
++ }
++
+ /* All the data is already mapped. Use it. */
+ if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
+ && (ALLOW_UNALIGNED
+--- elfutils-0.114/libelf/elf32_getshdr.c
++++ elfutils-0.114/libelf/elf32_getshdr.c
+@@ -66,11 +66,12 @@ elfw2(LIBELFBITS,getshdr) (scn)
+ goto out;
+
+ size_t shnum;
+- if (INTUSE (elf_getshnum) (elf, &shnum) != 0)
++ if (INTUSE (elf_getshnum) (elf, &shnum) != 0
++ || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
+ goto out;
+ size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
+
+- /* Allocate memory for the program headers. We know the number
++ /* Allocate memory for the section headers. We know the number
+ of entries from the ELF header. */
+ ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
+ (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
+@@ -92,6 +93,16 @@ elfw2(LIBELFBITS,getshdr) (scn)
+ && (ehdr->e_shoff
+ & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
+
++ /* First see whether the information in the ELF header is
++ valid and it does not ask for too much. */
++ if (unlikely (ehdr->e_shoff >= elf->maximum_size)
++ || unlikely (ehdr->e_shoff + size > elf->maximum_size))
++ {
++ /* Something is wrong. */
++ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
++ goto free_and_out;
++ }
++
+ /* Now copy the data and at the same time convert the byte
+ order. */
+ if (ALLOW_UNALIGNED
+--- elfutils-0.114/libelf/elf32_newphdr.c
++++ elfutils-0.114/libelf/elf32_newphdr.c
@@ -1,5 +1,5 @@
- /* Get REL relocation information at given index.
-- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
-+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+ /* Create new ELF program header table.
+- Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
++ Copyright (C) 1999, 2000, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 1998.
This program is free software; you can redistribute it and/or modify
-@@ -38,12 +38,6 @@ gelf_getrel (data, ndx, dst)
- if (data_scn == NULL)
- return NULL;
-
-- if (unlikely (ndx < 0))
-- {
-- __libelf_seterrno (ELF_E_INVALID_INDEX);
-- return NULL;
-- }
--
- if (unlikely (data_scn->d.d_type != ELF_T_REL))
+@@ -91,6 +91,12 @@ elfw2(LIBELFBITS,newphdr) (elf, count)
+ else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count
+ || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
{
- __libelf_seterrno (ELF_E_INVALID_HANDLE);
-@@ -60,7 +54,8 @@ gelf_getrel (data, ndx, dst)
- if (scn->elf->class == ELFCLASS32)
++ if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
++ {
++ result = NULL;
++ goto out;
++ }
++
+ /* Allocate a new program header with the appropriate number of
+ elements. */
+ result = (ElfW2(LIBELFBITS,Phdr) *)
+--- elfutils-0.114/libelf/elf32_updatefile.c
++++ elfutils-0.114/libelf/elf32_updatefile.c
+@@ -164,6 +164,9 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf
+ /* Write all the sections. Well, only those which are modified. */
+ if (shnum > 0)
{
- /* We have to convert the data. */
-- if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf32_Rel)
-+ || unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
++ if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *)))
++ return 1;
++
+ ElfW2(LIBELFBITS,Shdr) *shdr_dest;
+ Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+ Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *));
+@@ -468,6 +471,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf
+ /* Write all the sections. Well, only those which are modified. */
+ if (shnum > 0)
+ {
++ if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *)
++ + sizeof (ElfW2(LIBELFBITS,Shdr)))))
++ return 1;
++
+ off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
+ #if EV_NUM != 2
+ xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
+--- elfutils-0.114/libelf/elf_begin.c
++++ elfutils-0.114/libelf/elf_begin.c
+@@ -82,7 +82,11 @@ get_shnum (void *map_address, unsigned c
+ || (((size_t) ((char *) map_address + offset))
+ & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
+ - 1)) == 0))
+- ehdr.p = (char *) map_address + offset;
++ {
++ ehdr.p = (char *) map_address + offset;
++ if (maxsize < (is32 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
++ return (size_t) -1l;
++ }
+ else
+ {
+ /* We have to read the data from the file. */
+@@ -122,7 +126,8 @@ get_shnum (void *map_address, unsigned c
+
+ if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
{
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- result = NULL;
-@@ -80,7 +75,8 @@ gelf_getrel (data, ndx, dst)
+- if (offset + ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)
++ if (unlikely (ehdr.e32->e_shoff >= maxsize)
++ || unlikely (ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize))
+ /* Cannot read the first section header. */
+ return (size_t) -1l;
+
+@@ -167,7 +172,8 @@ get_shnum (void *map_address, unsigned c
+
+ if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
+ {
+- if (offset + ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)
++ if (unlikely (ehdr.e64->e_shoff >= maxsize)
++ || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
+ /* Cannot read the first section header. */
+ return (size_t) -1l;
+
+@@ -258,6 +264,15 @@ file_read_elf (int fildes, void *map_add
+ /* Could not determine the number of sections. */
+ return NULL;
+
++ /* Check for too many sections. */
++ if (e_ident[EI_CLASS] == ELFCLASS32)
++ {
++ if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
++ return NULL;
++ }
++ else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
++ return NULL;
++
+ /* We can now allocate the memory. */
+ elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+ ELF_K_ELF, scncnt * sizeof (Elf_Scn));
+@@ -289,15 +304,31 @@ file_read_elf (int fildes, void *map_add
+ /* We can use the mmapped memory. */
+ elf->state.elf32.ehdr =
+ (Elf32_Ehdr *) ((char *) map_address + offset);
++ if (unlikely (elf->state.elf32.ehdr->e_shoff >= maxsize)
++ || unlikely (elf->state.elf32.ehdr->e_shoff
++ + scncnt * sizeof (Elf32_Shdr) > maxsize))
++ {
++ free_and_out:
++ __libelf_seterrno (ELF_E_INVALID_FILE);
++ free (elf);
++ return NULL;
++ }
+ elf->state.elf32.shdr =
+ (Elf32_Shdr *) ((char *) map_address + offset
+ + elf->state.elf32.ehdr->e_shoff);
+ if (elf->state.elf32.ehdr->e_phnum)
+- /* Assign a value only if there really is a program
+- header. Otherwise the value remains NULL. */
+- elf->state.elf32.phdr
+- = (Elf32_Phdr *) ((char *) map_address + offset
+- + elf->state.elf32.ehdr->e_phoff);
++ {
++ /* Assign a value only if there really is a program
++ header. Otherwise the value remains NULL. */
++ if (unlikely (elf->state.elf32.ehdr->e_phoff >= maxsize)
++ || unlikely (elf->state.elf32.ehdr->e_phoff
++ + elf->state.elf32.ehdr->e_phnum
++ * sizeof (Elf32_Phdr) > maxsize))
++ goto free_and_out;
++ elf->state.elf32.phdr
++ = (Elf32_Phdr *) ((char *) map_address + offset
++ + elf->state.elf32.ehdr->e_phoff);
++ }
+
+ for (size_t cnt = 0; cnt < scncnt; ++cnt)
+ {
+@@ -326,8 +357,7 @@ file_read_elf (int fildes, void *map_add
+ != sizeof (Elf32_Ehdr))
+ {
+ /* We must be able to read the ELF header. */
+- __libelf_seterrno (ELF_E_INVALID_FILE);
+- return NULL;
++ goto free_and_out;
+ }
+
+ if (e_ident[EI_DATA] != MY_ELFDATA)
+@@ -381,15 +411,26 @@ file_read_elf (int fildes, void *map_add
+ /* We can use the mmapped memory. */
+ elf->state.elf64.ehdr =
+ (Elf64_Ehdr *) ((char *) map_address + offset);
++ if (unlikely (elf->state.elf64.ehdr->e_shoff >= maxsize)
++ || unlikely (elf->state.elf64.ehdr->e_shoff
++ + scncnt * sizeof (Elf64_Shdr) > maxsize))
++ goto free_and_out;
+ elf->state.elf64.shdr =
+ (Elf64_Shdr *) ((char *) map_address + offset
+ + elf->state.elf64.ehdr->e_shoff);
+ if (elf->state.elf64.ehdr->e_phnum)
+- /* Assign a value only if there really is a program
+- header. Otherwise the value remains NULL. */
+- elf->state.elf64.phdr
+- = (Elf64_Phdr *) ((char *) map_address + offset
+- + elf->state.elf64.ehdr->e_phoff);
++ {
++ /* Assign a value only if there really is a program
++ header. Otherwise the value remains NULL. */
++ if (unlikely (elf->state.elf64.ehdr->e_phoff >= maxsize)
++ || unlikely (elf->state.elf64.ehdr->e_phoff
++ + elf->state.elf64.ehdr->e_phnum
++ * sizeof (Elf64_Phdr) > maxsize))
++ goto free_and_out;
++ elf->state.elf64.phdr
++ = (Elf64_Phdr *) ((char *) map_address + offset
++ + elf->state.elf64.ehdr->e_phoff);
++ }
+
+ for (size_t cnt = 0; cnt < scncnt; ++cnt)
+ {
+@@ -418,8 +459,7 @@ file_read_elf (int fildes, void *map_add
+ != sizeof (Elf64_Ehdr))
+ {
+ /* We must be able to read the ELF header. */
+- __libelf_seterrno (ELF_E_INVALID_FILE);
+- return NULL;
++ goto free_and_out;
+ }
+
+ if (e_ident[EI_DATA] != MY_ELFDATA)
+--- elfutils-0.114/libelf/elf_getarsym.c
++++ elfutils-0.114/libelf/elf_getarsym.c
+@@ -149,6 +149,9 @@ elf_getarsym (elf, ptr)
+ size_t index_size = atol (tmpbuf);
+
+ if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size
++#if SIZE_MAX <= 4294967295U
++ || n >= SIZE_MAX / sizeof (Elf_Arsym)
++#endif
+ || n * sizeof (uint32_t) > index_size)
+ {
+ /* This index table cannot be right since it does not fit into
+--- elfutils-0.114/libelf/elf_getshstrndx.c
++++ elfutils-0.114/libelf/elf_getshstrndx.c
+@@ -1,5 +1,5 @@
+ /* Return section index of section header string table.
+- Copyright (C) 2002 Red Hat, Inc.
++ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ This program is free software; you can redistribute it and/or modify
+@@ -90,10 +90,25 @@ elf_getshstrndx (elf, dst)
+ if (elf->map_address != NULL
+ && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
+ && (ALLOW_UNALIGNED
+- || (((size_t) ((char *) elf->map_address + offset))
++ || (((size_t) ((char *) elf->map_address
++ + elf->start_offset + offset))
+ & (__alignof__ (Elf32_Shdr) - 1)) == 0))
+- /* We can directly access the memory. */
+- num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link;
++ {
++ /* First see whether the information in the ELF header is
++ valid and it does not ask for too much. */
++ if (unlikely (offset + sizeof (Elf32_Shdr)
++ > elf->maximum_size))
++ {
++ /* Something is wrong. */
++ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
++ result = -1;
++ goto out;
++ }
++
++ /* We can directly access the memory. */
++ num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
++ + offset))->sh_link;
++ }
+ else
+ {
+ /* We avoid reading in all the section headers. Just read
+@@ -129,10 +144,25 @@ elf_getshstrndx (elf, dst)
+ if (elf->map_address != NULL
+ && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
+ && (ALLOW_UNALIGNED
+- || (((size_t) ((char *) elf->map_address + offset))
++ || (((size_t) ((char *) elf->map_address
++ + elf->start_offset + offset))
+ & (__alignof__ (Elf64_Shdr) - 1)) == 0))
+- /* We can directly access the memory. */
+- num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link;
++ {
++ /* First see whether the information in the ELF header is
++ valid and it does not ask for too much. */
++ if (unlikely (offset + sizeof (Elf64_Shdr)
++ > elf->maximum_size))
++ {
++ /* Something is wrong. */
++ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
++ result = -1;
++ goto out;
++ }
++
++ /* We can directly access the memory. */
++ num = ((Elf64_Shdr *) (elf->map_address
++ + elf->start_offset + offset))->sh_link;
++ }
+ else
+ {
+ /* We avoid reading in all the section headers. Just read
+--- elfutils-0.114/libelf/elf_newscn.c
++++ elfutils-0.114/libelf/elf_newscn.c
+@@ -1,5 +1,5 @@
+ /* Append new section.
+- Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
++ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+ This program is free software; you can redistribute it and/or modify
+@@ -71,13 +71,21 @@ elf_newscn (elf)
+ else
{
- /* Simply copy the data after we made sure we are actually getting
- correct data. */
-- if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf64_Rel)
-+ || unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
+ /* We must allocate a new element. */
+- Elf_ScnList *newp;
++ Elf_ScnList *newp = NULL;
+
+ assert (elf->state.elf.scnincr > 0);
+
+- newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
+- + ((elf->state.elf.scnincr *= 2)
+- * sizeof (Elf_Scn)), 1);
++ if (
++#if SIZE_MAX <= 4294967295U
++ likely (elf->state.elf.scnincr
++ < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList))
++#else
++ 1
++#endif
++ )
++ newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
++ + ((elf->state.elf.scnincr *= 2)
++ * sizeof (Elf_Scn)), 1);
+ if (newp == NULL)
{
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- result = NULL;
---- elfutils-0.108/libelf/gelf_getsym.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getsym.c 2005-05-14 01:31:25.000000000 +0200
+ __libelf_seterrno (ELF_E_NOMEM);
+--- elfutils-0.114/libelf/gelf_getdyn.c
++++ elfutils-0.114/libelf/gelf_getdyn.c
@@ -1,5 +1,5 @@
- /* Get symbol information from symbol table at the given index.
-- Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
-+ Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+ /* Get information from dynamic table at the given index.
+- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
++ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -57,7 +57,8 @@ gelf_getsym (data, ndx, dst)
+@@ -60,7 +60,8 @@ gelf_getdyn (data, ndx, dst)
table entries has to be adopted. The user better has provided
a buffer where we can store the information. While copying the
data we are converting the format. */
-- if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size))
-+ if (INVALID_NDX (ndx, Elf32_Sym)
-+ || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size))
+- if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf32_Dyn)
++ || unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
-@@ -86,7 +87,8 @@ gelf_getsym (data, ndx, dst)
+@@ -81,7 +82,8 @@ gelf_getdyn (data, ndx, dst)
/* The data is already in the correct form. Just make sure the
index is OK. */
-- if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size))
-+ if (INVALID_NDX (ndx, GElf_Sym)
-+ || unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size))
+- if (unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, GElf_Dyn)
++ || unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/libelf/gelf_update_sym.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_sym.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_getlib.c
++++ elfutils-0.114/libelf/gelf_getlib.c
@@ -1,5 +1,5 @@
- /* Update symbol information in symbol table at the given index.
+ /* Get library from table at the given index.
+- Copyright (C) 2004 Red Hat, Inc.
++ Copyright (C) 2004, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ This program is free software; you can redistribute it and/or modify
+@@ -53,7 +53,8 @@ gelf_getlib (data, ndx, dst)
+ /* The data is already in the correct form. Just make sure the
+ index is OK. */
+ GElf_Lib *result = NULL;
+- if (unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size))
++ if (INVALID_NDX (ndx, GElf_Lib)
++ || unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size))
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ else
+ {
+--- elfutils-0.114/libelf/gelf_getmove.c
++++ elfutils-0.114/libelf/gelf_getmove.c
+@@ -1,5 +1,5 @@
+ /* Get move structure at the given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -39,12 +39,6 @@ gelf_update_sym (data, ndx, src)
- if (data == NULL)
- return 0;
-
-- if (unlikely (ndx < 0))
-- {
-- __libelf_seterrno (ELF_E_INVALID_INDEX);
-- return 0;
-- }
--
- if (unlikely (data_scn->d.d_type != ELF_T_SYM))
- {
- /* The type of the data better should match. */
-@@ -69,7 +63,8 @@ gelf_update_sym (data, ndx, src)
- }
+@@ -50,7 +50,8 @@ gelf_getmove (data, ndx, dst)
- /* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf32_Sym)
-+ || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size))
- {
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- goto out;
-@@ -92,7 +87,8 @@ gelf_update_sym (data, ndx, src)
- else
+ /* The data is already in the correct form. Just make sure the
+ index is OK. */
+- if (unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size))
++ if (INVALID_NDX (ndx, GElf_Move)
++ || unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size))
{
- /* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf64_Sym)
-+ || unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size))
- {
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- goto out;
---- elfutils-0.108/libelf/gelf_getrela.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getrela.c 2005-05-14 01:31:25.000000000 +0200
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ goto out;
+--- elfutils-0.114/libelf/gelf_getrela.c
++++ elfutils-0.114/libelf/gelf_getrela.c
@@ -1,5 +1,5 @@
/* Get RELA relocation information at given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
@@ -220,168 +526,98 @@ src/
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
result = NULL;
---- elfutils-0.108/libelf/gelf_update_syminfo.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_syminfo.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_getrel.c
++++ elfutils-0.114/libelf/gelf_getrel.c
@@ -1,5 +1,5 @@
- /* Update additional symbol information in symbol table at the given index.
+ /* Get REL relocation information at given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -39,12 +39,6 @@ gelf_update_syminfo (data, ndx, src)
- if (data == NULL)
- return 0;
+@@ -38,12 +38,6 @@ gelf_getrel (data, ndx, dst)
+ if (data_scn == NULL)
+ return NULL;
- if (unlikely (ndx < 0))
- {
- __libelf_seterrno (ELF_E_INVALID_INDEX);
-- return 0;
+- return NULL;
- }
-
- if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO))
- {
- /* The type of the data better should match. */
-@@ -60,7 +54,8 @@ gelf_update_syminfo (data, ndx, src)
- rwlock_wrlock (scn->elf->lock);
-
- /* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, GElf_Syminfo)
-+ || unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size))
+ if (unlikely (data_scn->d.d_type != ELF_T_REL))
{
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- goto out;
---- elfutils-0.108/libelf/gelf_getsyminfo.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getsyminfo.c 2005-05-14 01:31:25.000000000 +0200
-@@ -1,5 +1,5 @@
- /* Get additional symbol information from symbol table at the given index.
-- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
-+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2000.
-
- This program is free software; you can redistribute it and/or modify
-@@ -51,7 +51,8 @@ gelf_getsyminfo (data, ndx, dst)
-
- /* The data is already in the correct form. Just make sure the
- index is OK. */
-- if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size))
-+ if (INVALID_NDX (ndx, GElf_Syminfo)
-+ || unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size))
+ __libelf_seterrno (ELF_E_INVALID_HANDLE);
+@@ -60,7 +54,8 @@ gelf_getrel (data, ndx, dst)
+ if (scn->elf->class == ELFCLASS32)
{
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- goto out;
---- elfutils-0.108/libelf/elf_newscn.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/elf_newscn.c 2005-05-14 01:38:35.000000000 +0200
-@@ -1,5 +1,5 @@
- /* Append new section.
-- Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 1998.
-
- This program is free software; you can redistribute it and/or modify
-@@ -71,13 +71,21 @@ elf_newscn (elf)
- else
+ /* We have to convert the data. */
+- if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf32_Rel)
++ || unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
+ {
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ result = NULL;
+@@ -80,7 +75,8 @@ gelf_getrel (data, ndx, dst)
{
- /* We must allocate a new element. */
-- Elf_ScnList *newp;
-+ Elf_ScnList *newp = NULL;
-
- assert (elf->state.elf.scnincr > 0);
-
-- newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
-- + ((elf->state.elf.scnincr *= 2)
-- * sizeof (Elf_Scn)), 1);
-+ if (
-+#if SIZE_MAX <= 4294967295U
-+ likely (elf->state.elf.scnincr
-+ < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList))
-+#else
-+ 1
-+#endif
-+ )
-+ newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
-+ + ((elf->state.elf.scnincr *= 2)
-+ * sizeof (Elf_Scn)), 1);
- if (newp == NULL)
+ /* Simply copy the data after we made sure we are actually getting
+ correct data. */
+- if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf64_Rel)
++ || unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
{
- __libelf_seterrno (ELF_E_NOMEM);
---- elfutils-0.108/libelf/gelf_update_lib.c.jj 2004-01-23 19:23:03.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_lib.c 2005-05-14 01:31:25.000000000 +0200
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ result = NULL;
+--- elfutils-0.114/libelf/gelf_getsym.c
++++ elfutils-0.114/libelf/gelf_getsym.c
@@ -1,5 +1,5 @@
- /* Update library in table at the given index.
-- Copyright (C) 2004 Red Hat, Inc.
-+ Copyright (C) 2004, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+ /* Get symbol information from symbol table at the given index.
+- Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
++ Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 1999.
This program is free software; you can redistribute it and/or modify
-@@ -35,12 +35,6 @@ gelf_update_lib (data, ndx, src)
- if (data == NULL)
- return 0;
-
-- if (unlikely (ndx < 0))
-- {
-- __libelf_seterrno (ELF_E_INVALID_INDEX);
-- return 0;
-- }
--
- Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
- if (unlikely (data_scn->d.d_type != ELF_T_LIB))
- {
-@@ -54,7 +48,8 @@ gelf_update_lib (data, ndx, src)
+@@ -57,7 +57,8 @@ gelf_getsym (data, ndx, dst)
+ table entries has to be adopted. The user better has provided
+ a buffer where we can store the information. While copying the
+ data we are converting the format. */
+- if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size))
++ if (INVALID_NDX (ndx, Elf32_Sym)
++ || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size))
+ {
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ goto out;
+@@ -86,7 +87,8 @@ gelf_getsym (data, ndx, dst)
- /* Check whether we have to resize the data buffer. */
- int result = 0;
-- if (unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf64_Lib)
-+ || unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size))
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- else
- {
---- elfutils-0.108/libelf/gelf_getmove.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getmove.c 2005-05-14 01:31:25.000000000 +0200
+ /* The data is already in the correct form. Just make sure the
+ index is OK. */
+- if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size))
++ if (INVALID_NDX (ndx, GElf_Sym)
++ || unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size))
+ {
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ goto out;
+--- elfutils-0.114/libelf/gelf_getsyminfo.c
++++ elfutils-0.114/libelf/gelf_getsyminfo.c
@@ -1,5 +1,5 @@
- /* Get move structure at the given index.
+ /* Get additional symbol information from symbol table at the given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -50,7 +50,8 @@ gelf_getmove (data, ndx, dst)
+@@ -51,7 +51,8 @@ gelf_getsyminfo (data, ndx, dst)
/* The data is already in the correct form. Just make sure the
index is OK. */
-- if (unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size))
-+ if (INVALID_NDX (ndx, GElf_Move)
-+ || unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size))
+- if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size))
++ if (INVALID_NDX (ndx, GElf_Syminfo)
++ || unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/libelf/elf32_updatefile.c.jj 2005-02-06 10:14:52.000000000 +0100
-+++ elfutils-0.108/libelf/elf32_updatefile.c 2005-05-14 00:45:03.000000000 +0200
-@@ -164,6 +164,9 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf
- /* Write all the sections. Well, only those which are modified. */
- if (shnum > 0)
- {
-+ if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *)))
-+ return 1;
-+
- ElfW2(LIBELFBITS,Shdr) *shdr_dest;
- Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
- Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *));
-@@ -468,6 +471,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf
- /* Write all the sections. Well, only those which are modified. */
- if (shnum > 0)
- {
-+ if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *)
-+ + sizeof (ElfW2(LIBELFBITS,Shdr)))))
-+ return 1;
-+
- off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
- #if EV_NUM != 2
- xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
---- elfutils-0.108/libelf/gelf_getsymshndx.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getsymshndx.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_getsymshndx.c
++++ elfutils-0.114/libelf/gelf_getsymshndx.c
@@ -1,6 +1,6 @@
/* Get symbol information and separate section index from symbol table
at the given index.
@@ -421,26 +657,27 @@ src/
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/libelf/gelf_update_move.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_move.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_getversym.c
++++ elfutils-0.114/libelf/gelf_getversym.c
@@ -1,5 +1,5 @@
- /* Update move structure at the given index.
-- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
-+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+ /* Get symbol version information at the given index.
+- Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
++ Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 1999.
This program is free software; you can redistribute it and/or modify
-@@ -42,7 +42,7 @@ gelf_update_move (data, ndx, src)
- assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
+@@ -59,7 +59,8 @@ gelf_getversym (data, ndx, dst)
- /* Check whether we have to resize the data buffer. */
-- if (unlikely (ndx < 0)
-+ if (INVALID_NDX (ndx, GElf_Move)
- || unlikely ((ndx + 1) * sizeof (GElf_Move) > data_scn->d.d_size))
+ /* The data is already in the correct form. Just make sure the
+ index is OK. */
+- if (unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size))
++ if (INVALID_NDX (ndx, GElf_Versym)
++ || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
---- elfutils-0.108/libelf/gelf_update_dyn.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_dyn.c 2005-05-14 01:31:25.000000000 +0200
+ result = NULL;
+--- elfutils-0.114/libelf/gelf_update_dyn.c
++++ elfutils-0.114/libelf/gelf_update_dyn.c
@@ -1,5 +1,5 @@
/* Update information in dynamic table at the given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
@@ -481,146 +718,109 @@ src/
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/libelf/elf_begin.c.jj 2005-05-09 06:33:49.000000000 +0200
-+++ elfutils-0.108/libelf/elf_begin.c 2005-05-14 00:29:34.000000000 +0200
-@@ -220,7 +220,7 @@ file_read_elf (int fildes, void *map_add
-
- /* Determine the number of sections. */
- scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
-- if (scncnt == (size_t) -1l)
-+ if (scncnt == (size_t) -1l || scncnt > SIZE_MAX / sizeof (Elf_Scn))
- /* Could not determine the number of sections. */
- return NULL;
-
---- elfutils-0.108/libelf/gelf_getversym.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getversym.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_update_lib.c
++++ elfutils-0.114/libelf/gelf_update_lib.c
@@ -1,5 +1,5 @@
- /* Get symbol version information at the given index.
-- Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
-+ Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+ /* Update library in table at the given index.
+- Copyright (C) 2004 Red Hat, Inc.
++ Copyright (C) 2004, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2004.
This program is free software; you can redistribute it and/or modify
-@@ -59,7 +59,8 @@ gelf_getversym (data, ndx, dst)
+@@ -35,12 +35,6 @@ gelf_update_lib (data, ndx, src)
+ if (data == NULL)
+ return 0;
- /* The data is already in the correct form. Just make sure the
- index is OK. */
-- if (unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size))
-+ if (INVALID_NDX (ndx, GElf_Versym)
-+ || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size))
+- if (unlikely (ndx < 0))
+- {
+- __libelf_seterrno (ELF_E_INVALID_INDEX);
+- return 0;
+- }
+-
+ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+ if (unlikely (data_scn->d.d_type != ELF_T_LIB))
{
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- result = NULL;
---- elfutils-0.108/libelf/elf32_newphdr.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/elf32_newphdr.c 2005-05-14 01:17:53.000000000 +0200
+@@ -54,7 +48,8 @@ gelf_update_lib (data, ndx, src)
+
+ /* Check whether we have to resize the data buffer. */
+ int result = 0;
+- if (unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf64_Lib)
++ || unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size))
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+ else
+ {
+--- elfutils-0.114/libelf/gelf_update_move.c
++++ elfutils-0.114/libelf/gelf_update_move.c
@@ -1,5 +1,5 @@
- /* Create new ELF program header table.
-- Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
-+ Copyright (C) 1999, 2000, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+ /* Update move structure at the given index.
+- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
++ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -91,6 +91,12 @@ elfw2(LIBELFBITS,newphdr) (elf, count)
- else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count
- || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+@@ -42,7 +42,7 @@ gelf_update_move (data, ndx, src)
+ assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
+
+ /* Check whether we have to resize the data buffer. */
+- if (unlikely (ndx < 0)
++ if (INVALID_NDX (ndx, GElf_Move)
+ || unlikely ((ndx + 1) * sizeof (GElf_Move) > data_scn->d.d_size))
{
-+ if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
-+ {
-+ result = NULL;
-+ goto out;
-+ }
-+
- /* Allocate a new program header with the appropriate number of
- elements. */
- result = (ElfW2(LIBELFBITS,Phdr) *)
---- elfutils-0.108/libelf/gelf_getdyn.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getdyn.c 2005-05-14 01:31:25.000000000 +0200
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+--- elfutils-0.114/libelf/gelf_update_rela.c
++++ elfutils-0.114/libelf/gelf_update_rela.c
@@ -1,5 +1,5 @@
- /* Get information from dynamic table at the given index.
+ /* Update RELA relocation information at given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -60,7 +60,8 @@ gelf_getdyn (data, ndx, dst)
- table entries has to be adopted. The user better has provided
- a buffer where we can store the information. While copying the
- data we are converting the format. */
-- if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf32_Dyn)
-+ || unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
+@@ -35,12 +35,6 @@ gelf_update_rela (Elf_Data *dst, int ndx
+ if (dst == NULL)
+ return 0;
+
+- if (unlikely (ndx < 0))
+- {
+- __libelf_seterrno (ELF_E_INVALID_INDEX);
+- return 0;
+- }
+-
+ if (unlikely (data_scn->d.d_type != ELF_T_RELA))
+ {
+ /* The type of the data better should match. */
+@@ -68,7 +62,8 @@ gelf_update_rela (Elf_Data *dst, int ndx
+ }
+
+ /* Check whether we have to resize the data buffer. */
+- if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf32_Rela)
++ || unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
-@@ -81,7 +82,8 @@ gelf_getdyn (data, ndx, dst)
-
- /* The data is already in the correct form. Just make sure the
- index is OK. */
-- if (unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, GElf_Dyn)
-+ || unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size))
+@@ -84,7 +79,8 @@ gelf_update_rela (Elf_Data *dst, int ndx
+ else
+ {
+ /* Check whether we have to resize the data buffer. */
+- if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf64_Rela)
++ || unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/libelf/elf_getarsym.c.jj 2005-02-06 10:14:52.000000000 +0100
-+++ elfutils-0.108/libelf/elf_getarsym.c 2005-05-14 01:37:47.000000000 +0200
-@@ -144,6 +144,9 @@ elf_getarsym (elf, ptr)
- size_t index_size = atol (tmpbuf);
-
- if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size
-+#if SIZE_MAX <= 4294967295U
-+ || n >= SIZE_MAX / sizeof (Elf_Arsym)
-+#endif
- || n * sizeof (uint32_t) > index_size)
- {
- /* This index table cannot be right since it does not fit into
---- elfutils-0.108/libelf/libelfP.h.jj 2005-03-30 03:42:32.000000000 +0200
-+++ elfutils-0.108/libelf/libelfP.h 2005-05-14 01:28:47.000000000 +0200
-@@ -531,4 +531,13 @@ extern uint32_t __libelf_crc32 (uint32_t
- } while (0)
- #endif
-
-+/* Convenience macro. Assumes int NDX and TYPE with size at least
-+ 2 bytes. */
-+#if SIZE_MAX > 4294967295U
-+# define INVALID_NDX(ndx, type) unlikely (ndx < 0)
-+#else
-+# define INVALID_NDX(ndx, type) \
-+ unlikely ((unsigned int) (ndx) >= SIZE_MAX / sizeof (type))
-+#endif
-+
- #endif /* libelfP.h */
---- elfutils-0.108/libelf/gelf_getlib.c.jj 2004-01-23 19:22:56.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_getlib.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_update_rel.c
++++ elfutils-0.114/libelf/gelf_update_rel.c
@@ -1,5 +1,5 @@
- /* Get library from table at the given index.
-- Copyright (C) 2004 Red Hat, Inc.
-+ Copyright (C) 2004, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2004.
-
- This program is free software; you can redistribute it and/or modify
-@@ -53,7 +53,8 @@ gelf_getlib (data, ndx, dst)
- /* The data is already in the correct form. Just make sure the
- index is OK. */
- GElf_Lib *result = NULL;
-- if (unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size))
-+ if (INVALID_NDX (ndx, GElf_Lib)
-+ || unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size))
- __libelf_seterrno (ELF_E_INVALID_INDEX);
- else
- {
---- elfutils-0.108/libelf/gelf_update_symshndx.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_symshndx.c 2005-05-14 01:31:25.000000000 +0200
-@@ -1,6 +1,6 @@
- /* Update symbol information and section index in symbol table at the
- given index.
+ /* Update REL relocation information at given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -44,12 +44,6 @@ gelf_update_symshndx (symdata, shndxdata
- if (symdata == NULL)
+@@ -35,12 +35,6 @@ gelf_update_rel (Elf_Data *dst, int ndx,
+ if (dst == NULL)
return 0;
- if (unlikely (ndx < 0))
@@ -629,52 +829,40 @@ src/
- return 0;
- }
-
- if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
+ if (unlikely (data_scn->d.d_type != ELF_T_REL))
{
/* The type of the data better should match. */
-@@ -95,7 +89,8 @@ gelf_update_symshndx (symdata, shndxdata
+@@ -66,7 +60,8 @@ gelf_update_rel (Elf_Data *dst, int ndx,
}
/* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf32_Sym)
-+ || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
+- if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf32_Rel)
++ || unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
-@@ -118,7 +113,8 @@ gelf_update_symshndx (symdata, shndxdata
+@@ -81,7 +76,8 @@ gelf_update_rel (Elf_Data *dst, int ndx,
else
{
/* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf64_Sym)
-+ || unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
+- if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf64_Rel)
++ || unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/libelf/elf32_getshdr.c.jj 2005-02-06 10:14:52.000000000 +0100
-+++ elfutils-0.108/libelf/elf32_getshdr.c 2005-05-14 00:32:57.000000000 +0200
-@@ -66,7 +66,8 @@ elfw2(LIBELFBITS,getshdr) (scn)
- goto out;
-
- size_t shnum;
-- if (INTUSE (elf_getshnum) (elf, &shnum) != 0)
-+ if (INTUSE (elf_getshnum) (elf, &shnum) != 0
-+ || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
- goto out;
- size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
-
---- elfutils-0.108/libelf/gelf_update_rela.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_rela.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_update_sym.c
++++ elfutils-0.114/libelf/gelf_update_sym.c
@@ -1,5 +1,5 @@
- /* Update RELA relocation information at given index.
+ /* Update symbol information in symbol table at the given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -35,12 +35,6 @@ gelf_update_rela (Elf_Data *dst, int ndx
- if (dst == NULL)
+@@ -39,12 +39,6 @@ gelf_update_sym (data, ndx, src)
+ if (data == NULL)
return 0;
- if (unlikely (ndx < 0))
@@ -683,58 +871,73 @@ src/
- return 0;
- }
-
- if (unlikely (data_scn->d.d_type != ELF_T_RELA))
+ if (unlikely (data_scn->d.d_type != ELF_T_SYM))
{
/* The type of the data better should match. */
-@@ -68,7 +62,8 @@ gelf_update_rela (Elf_Data *dst, int ndx
+@@ -69,7 +63,8 @@ gelf_update_sym (data, ndx, src)
}
/* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf32_Rela)
-+ || unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
+- if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf32_Sym)
++ || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
-@@ -84,7 +79,8 @@ gelf_update_rela (Elf_Data *dst, int ndx
+@@ -92,7 +87,8 @@ gelf_update_sym (data, ndx, src)
else
{
/* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf64_Rela)
-+ || unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
+- if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf64_Sym)
++ || unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/libelf/gelf_update_versym.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_versym.c 2005-05-14 01:31:25.000000000 +0200
+--- elfutils-0.114/libelf/gelf_update_syminfo.c
++++ elfutils-0.114/libelf/gelf_update_syminfo.c
@@ -1,5 +1,5 @@
- /* Update symbol version information.
-- Copyright (C) 2001, 2002 Red Hat, Inc.
-+ Copyright (C) 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+ /* Update additional symbol information in symbol table at the given index.
+- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
++ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -42,7 +42,7 @@ gelf_update_versym (data, ndx, src)
- assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
+@@ -39,12 +39,6 @@ gelf_update_syminfo (data, ndx, src)
+ if (data == NULL)
+ return 0;
+
+- if (unlikely (ndx < 0))
+- {
+- __libelf_seterrno (ELF_E_INVALID_INDEX);
+- return 0;
+- }
+-
+ if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO))
+ {
+ /* The type of the data better should match. */
+@@ -60,7 +54,8 @@ gelf_update_syminfo (data, ndx, src)
+ rwlock_wrlock (scn->elf->lock);
/* Check whether we have to resize the data buffer. */
-- if (unlikely (ndx < 0)
-+ if (INVALID_NDX (ndx, GElf_Versym)
- || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data_scn->d.d_size))
+- if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size))
++ if (INVALID_NDX (ndx, GElf_Syminfo)
++ || unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
---- elfutils-0.108/libelf/gelf_update_rel.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/gelf_update_rel.c 2005-05-14 01:31:25.000000000 +0200
-@@ -1,5 +1,5 @@
- /* Update REL relocation information at given index.
+ goto out;
+--- elfutils-0.114/libelf/gelf_update_symshndx.c
++++ elfutils-0.114/libelf/gelf_update_symshndx.c
+@@ -1,6 +1,6 @@
+ /* Update symbol information and section index in symbol table at the
+ given index.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
-@@ -35,12 +35,6 @@ gelf_update_rel (Elf_Data *dst, int ndx,
- if (dst == NULL)
+@@ -44,12 +44,6 @@ gelf_update_symshndx (symdata, shndxdata
+ if (symdata == NULL)
return 0;
- if (unlikely (ndx < 0))
@@ -743,31 +946,65 @@ src/
- return 0;
- }
-
- if (unlikely (data_scn->d.d_type != ELF_T_REL))
+ if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
{
/* The type of the data better should match. */
-@@ -66,7 +60,8 @@ gelf_update_rel (Elf_Data *dst, int ndx,
+@@ -95,7 +89,8 @@ gelf_update_symshndx (symdata, shndxdata
}
/* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf32_Rel)
-+ || unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
+- if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf32_Sym)
++ || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
-@@ -81,7 +76,8 @@ gelf_update_rel (Elf_Data *dst, int ndx,
+@@ -118,7 +113,8 @@ gelf_update_symshndx (symdata, shndxdata
else
{
/* Check whether we have to resize the data buffer. */
-- if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
-+ if (INVALID_NDX (ndx, Elf64_Rel)
-+ || unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
+- if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
++ if (INVALID_NDX (ndx, Elf64_Sym)
++ || unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
{
__libelf_seterrno (ELF_E_INVALID_INDEX);
goto out;
---- elfutils-0.108/src/elflint.c.jj 2005-05-07 01:46:26.000000000 +0200
-+++ elfutils-0.108/src/elflint.c 2005-05-14 02:22:24.000000000 +0200
+--- elfutils-0.114/libelf/gelf_update_versym.c
++++ elfutils-0.114/libelf/gelf_update_versym.c
+@@ -1,5 +1,5 @@
+ /* Update symbol version information.
+- Copyright (C) 2001, 2002 Red Hat, Inc.
++ Copyright (C) 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is free software; you can redistribute it and/or modify
+@@ -42,7 +42,7 @@ gelf_update_versym (data, ndx, src)
+ assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
+
+ /* Check whether we have to resize the data buffer. */
+- if (unlikely (ndx < 0)
++ if (INVALID_NDX (ndx, GElf_Versym)
+ || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data_scn->d.d_size))
+ {
+ __libelf_seterrno (ELF_E_INVALID_INDEX);
+--- elfutils-0.114/libelf/libelfP.h
++++ elfutils-0.114/libelf/libelfP.h
+@@ -536,4 +536,13 @@ extern uint32_t __libelf_crc32 (uint32_t
+ } while (0)
+ #endif
+
++/* Convenience macro. Assumes int NDX and TYPE with size at least
++ 2 bytes. */
++#if SIZE_MAX > 4294967295U
++# define INVALID_NDX(ndx, type) unlikely (ndx < 0)
++#else
++# define INVALID_NDX(ndx, type) \
++ unlikely ((unsigned int) (ndx) >= SIZE_MAX / sizeof (type))
++#endif
++
+ #endif /* libelfP.h */
+--- elfutils-0.114/src/elflint.c
++++ elfutils-0.114/src/elflint.c
@@ -111,6 +111,9 @@ static uint32_t shstrndx;
/* Array to count references in section groups. */
static int *scnref;
@@ -778,7 +1015,7 @@ src/
int
main (int argc, char *argv[])
-@@ -300,10 +303,17 @@ section_name (Ebl *ebl, int idx)
+@@ -300,10 +303,19 @@ section_name (Ebl *ebl, int idx)
{
GElf_Shdr shdr_mem;
GElf_Shdr *shdr;
@@ -788,6 +1025,8 @@ src/
+ return "<invalid>";
shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
++ if (shdr == NULL)
++ return "<invalid>";
- return elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+ ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
@@ -797,7 +1036,7 @@ src/
}
-@@ -325,10 +335,6 @@ static const int valid_e_machine[] =
+@@ -325,10 +337,6 @@ static const int valid_e_machine[] =
(sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))
@@ -808,9 +1047,9 @@ src/
static void
check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size)
{
-@@ -608,7 +614,8 @@ check_symtab (Ebl *ebl, GElf_Ehdr *ehdr,
- xndxdata = NULL;
- }
+@@ -591,7 +599,8 @@ section [%2d] '%s': symbol table cannot
+ }
+ }
- if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT))
+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT);
@@ -818,7 +1057,7 @@ src/
ERROR (gettext ("\
section [%2zu] '%s': entry size is does not match ElfXX_Sym\n"),
cnt, section_name (ebl, cnt));
-@@ -646,7 +653,7 @@ section [%2d] '%s': XINDEX for zeroth en
+@@ -629,7 +638,7 @@ section [%2d] '%s': XINDEX for zeroth en
xndxscnidx, section_name (ebl, xndxscnidx));
}
@@ -827,7 +1066,7 @@ src/
{
sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
if (sym == NULL)
-@@ -664,7 +671,8 @@ section [%2d] '%s': symbol %zu: invalid
+@@ -647,7 +656,8 @@ section [%2d] '%s': symbol %zu: invalid
else
{
name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
@@ -837,7 +1076,7 @@ src/
}
if (sym->st_shndx == SHN_XINDEX)
-@@ -954,7 +962,7 @@ is_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, i
+@@ -958,7 +968,7 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *e
const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem);
assert (rcshdr != NULL);
@@ -846,7 +1085,7 @@ src/
{
/* Found the dynamic section. Look through it. */
Elf_Data *d = elf_getdata (scn, NULL);
-@@ -964,14 +972,17 @@ is_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, i
+@@ -968,14 +978,17 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *e
{
GElf_Dyn dyn_mem;
GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem);
@@ -866,45 +1105,37 @@ src/
ERROR (gettext ("\
section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
idx, section_name (ebl, idx),
-@@ -1048,7 +1059,8 @@ section [%2d] '%s': no relocations for m
+@@ -1050,7 +1063,8 @@ section [%2d] '%s': no relocations for m
}
}
-- if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT))
-+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
+- if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT))
++ size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT);
+ if (shdr->sh_entsize != sh_entsize)
- ERROR (gettext ("\
- section [%2d] '%s': section entry size does not match ElfXX_Rela\n"),
- idx, section_name (ebl, idx));
-@@ -1058,7 +1070,7 @@ section [%2d] '%s': section entry size d
- GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+ ERROR (gettext (reltype == ELF_T_RELA ? "\
+ section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
+ section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
+@@ -1258,7 +1272,8 @@ check_rela (Ebl *ebl, GElf_Ehdr *ehdr, G
Elf_Data *symdata = elf_getdata (symscn, NULL);
+ enum load_state state = state_undecided;
-- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
-+ for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+- for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
++ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
++ for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
{
GElf_Rela rela_mem;
- GElf_Rela *rela;
-@@ -1183,7 +1195,8 @@ section [%2d] '%s': no relocations for m
- }
- }
-
-- if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT))
-+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
-+ if (shdr->sh_entsize != sh_entsize)
- ERROR (gettext ("\
- section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
- idx, section_name (ebl, idx));
-@@ -1193,7 +1206,7 @@ section [%2d] '%s': section entry size d
- GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+ GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
+@@ -1307,7 +1322,8 @@ check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GE
Elf_Data *symdata = elf_getdata (symscn, NULL);
+ enum load_state state = state_undecided;
-- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
-+ for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+- for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
++ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
++ for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
{
GElf_Rel rel_mem;
- GElf_Rel *rel;
-@@ -1341,7 +1354,8 @@ section [%2d] '%s': referenced as string
+ GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
+@@ -1408,7 +1424,8 @@ section [%2d] '%s': referenced as string
shdr->sh_link, section_name (ebl, shdr->sh_link),
idx, section_name (ebl, idx));
@@ -914,7 +1145,7 @@ src/
ERROR (gettext ("\
section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
idx, section_name (ebl, idx));
-@@ -1351,7 +1365,7 @@ section [%2d] '%s': section entry size d
+@@ -1418,7 +1435,7 @@ section [%2d] '%s': section entry size d
idx, section_name (ebl, idx));
bool non_null_warned = false;
@@ -922,8 +1153,8 @@ src/
+ for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
{
GElf_Dyn dyn_mem;
- GElf_Dyn *dyn;
-@@ -1502,6 +1516,8 @@ section [%2d] '%s': entry size does not
+ GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
+@@ -1559,6 +1576,8 @@ section [%2d] '%s': entry size does not
idx, section_name (ebl, idx));
if (symshdr != NULL
@@ -932,20 +1163,20 @@ src/
&& (shdr->sh_size / shdr->sh_entsize
< symshdr->sh_size / symshdr->sh_entsize))
ERROR (gettext ("\
-@@ -1530,6 +1546,12 @@ section [%2d] '%s': extended section ind
+@@ -1585,6 +1604,12 @@ section [%2d] '%s': extended section ind
}
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+ if (data == NULL)
+ {
+ ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
-+ idx, section_name (ebl, idx));
++ idx, section_name (ebl, idx));
+ return;
+ }
if (*((Elf32_Word *) data->d_buf) != 0)
ERROR (gettext ("symbol 0 should have zero extended section index\n"));
-@@ -1613,7 +1635,7 @@ section [%2d] '%s': hash table section i
+@@ -1665,23 +1690,30 @@ section [%2d] '%s': hash table section i
idx, section_name (ebl, idx), (long int) shdr->sh_size,
(long int) ((2 + nbucket + nchain) * shdr->sh_entsize));
@@ -954,294 +1185,6 @@ src/
{
size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
size_t cnt;
-@@ -1910,8 +1932,10 @@ section [%2d] '%s' refers in sh_link to
- return;
- }
-
-- if (shdr->sh_size / shdr->sh_entsize
-- != symshdr->sh_size / symshdr->sh_entsize)
-+ if (shdr->sh_entsize
-+ && symshdr->sh_entsize
-+ && shdr->sh_size / shdr->sh_entsize
-+ != symshdr->sh_size / symshdr->sh_entsize)
- ERROR (gettext ("\
- section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
- idx, section_name (ebl, idx),
-
---- elfutils-0.108/libelf/elf32_getphdr.c.jj 2005-02-06 10:14:52.000000000 +0100
-+++ elfutils-0.108/libelf/elf32_getphdr.c 2005-05-17 16:53:41.000000000 +0200
-@@ -80,6 +80,16 @@ elfw2(LIBELFBITS,getphdr) (elf)
-
- if (elf->map_address != NULL)
- {
-+ /* First see whether the information in the ELF header is
-+ valid and it does not ask for too much. */
-+ if (unlikely (ehdr->e_phoff >= elf->maximum_size)
-+ || unlikely (ehdr->e_phoff + size > elf->maximum_size))
-+ {
-+ /* Something is wrong. */
-+ __libelf_seterrno (ELF_E_INVALID_PHDR);
-+ goto out;
-+ }
-+
- /* All the data is already mapped. Use it. */
- if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
- && (ALLOW_UNALIGNED
---- elfutils-0.108/libelf/elf_getshstrndx.c.jj 2004-01-05 21:45:05.000000000 +0100
-+++ elfutils-0.108/libelf/elf_getshstrndx.c 2005-05-17 15:42:32.000000000 +0200
-@@ -1,5 +1,5 @@
- /* Return section index of section header string table.
-- Copyright (C) 2002 Red Hat, Inc.
-+ Copyright (C) 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2002.
-
- This program is free software; you can redistribute it and/or modify
-@@ -90,10 +90,25 @@ elf_getshstrndx (elf, dst)
- if (elf->map_address != NULL
- && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
- && (ALLOW_UNALIGNED
-- || (((size_t) ((char *) elf->map_address + offset))
-+ || (((size_t) ((char *) elf->map_address
-+ + elf->start_offset + offset))
- & (__alignof__ (Elf32_Shdr) - 1)) == 0))
-- /* We can directly access the memory. */
-- num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link;
-+ {
-+ /* First see whether the information in the ELF header is
-+ valid and it does not ask for too much. */
-+ if (unlikely (offset + sizeof (Elf32_Shdr)
-+ > elf->maximum_size))
-+ {
-+ /* Something is wrong. */
-+ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
-+ result = -1;
-+ goto out;
-+ }
-+
-+ /* We can directly access the memory. */
-+ num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
-+ + offset))->sh_link;
-+ }
- else
- {
- /* We avoid reading in all the section headers. Just read
-@@ -129,10 +144,25 @@ elf_getshstrndx (elf, dst)
- if (elf->map_address != NULL
- && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
- && (ALLOW_UNALIGNED
-- || (((size_t) ((char *) elf->map_address + offset))
-+ || (((size_t) ((char *) elf->map_address
-+ + elf->start_offset + offset))
- & (__alignof__ (Elf64_Shdr) - 1)) == 0))
-- /* We can directly access the memory. */
-- num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link;
-+ {
-+ /* First see whether the information in the ELF header is
-+ valid and it does not ask for too much. */
-+ if (unlikely (offset + sizeof (Elf64_Shdr)
-+ > elf->maximum_size))
-+ {
-+ /* Something is wrong. */
-+ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
-+ result = -1;
-+ goto out;
-+ }
-+
-+ /* We can directly access the memory. */
-+ num = ((Elf64_Shdr *) (elf->map_address
-+ + elf->start_offset + offset))->sh_link;
-+ }
- else
- {
- /* We avoid reading in all the section headers. Just read
---- elfutils-0.108/libelf/elf32_getshdr.c.jj 2005-05-14 00:32:57.000000000 +0200
-+++ elfutils-0.108/libelf/elf32_getshdr.c 2005-05-17 15:27:52.000000000 +0200
-@@ -71,7 +71,7 @@ elfw2(LIBELFBITS,getshdr) (scn)
- goto out;
- size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
-
-- /* Allocate memory for the program headers. We know the number
-+ /* Allocate memory for the section headers. We know the number
- of entries from the ELF header. */
- ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
- (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
-@@ -93,6 +93,16 @@ elfw2(LIBELFBITS,getshdr) (scn)
- && (ehdr->e_shoff
- & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
-
-+ /* First see whether the information in the ELF header is
-+ valid and it does not ask for too much. */
-+ if (unlikely (ehdr->e_shoff >= elf->maximum_size)
-+ || unlikely (ehdr->e_shoff + size > elf->maximum_size))
-+ {
-+ /* Something is wrong. */
-+ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
-+ goto free_and_out;
-+ }
-+
- /* Now copy the data and at the same time convert the byte
- order. */
- if (ALLOW_UNALIGNED
---- elfutils-0.108/libelf/elf_begin.c.jj 2005-05-17 16:18:51.000000000 +0200
-+++ elfutils-0.108/libelf/elf_begin.c 2005-05-17 17:31:37.000000000 +0200
-@@ -77,7 +77,11 @@ get_shnum (void *map_address, unsigned c
- || (((size_t) ((char *) map_address + offset))
- & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
- - 1)) == 0))
-- ehdr.p = (char *) map_address + offset;
-+ {
-+ ehdr.p = (char *) map_address + offset;
-+ if (maxsize < (is32 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
-+ return (size_t) -1l;
-+ }
- else
- {
- /* We have to read the data from the file. */
-@@ -111,7 +115,8 @@ get_shnum (void *map_address, unsigned c
-
- if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
- {
-- if (offset + ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)
-+ if (unlikely (ehdr.e32->e_shoff >= maxsize)
-+ || unlikely (ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize))
- /* Cannot read the first section header. */
- return (size_t) -1l;
-
-@@ -147,7 +152,8 @@ get_shnum (void *map_address, unsigned c
-
- if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
- {
-- if (offset + ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)
-+ if (unlikely (ehdr.e64->e_shoff >= maxsize)
-+ || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
- /* Cannot read the first section header. */
- return (size_t) -1l;
-
-@@ -220,10 +226,19 @@ file_read_elf (int fildes, void *map_add
-
- /* Determine the number of sections. */
- scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
-- if (scncnt == (size_t) -1l || scncnt > SIZE_MAX / sizeof (Elf_Scn))
-+ if (scncnt == (size_t) -1l)
- /* Could not determine the number of sections. */
- return NULL;
-
-+ /* Check for too many sections. */
-+ if (e_ident[EI_CLASS] == ELFCLASS32)
-+ {
-+ if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
-+ return NULL;
-+ }
-+ else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
-+ return NULL;
-+
- /* We can now allocate the memory. */
- elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
- ELF_K_ELF, scncnt * sizeof (Elf_Scn));
-@@ -255,15 +270,31 @@ file_read_elf (int fildes, void *map_add
- /* We can use the mmapped memory. */
- elf->state.elf32.ehdr =
- (Elf32_Ehdr *) ((char *) map_address + offset);
-+ if (unlikely (elf->state.elf32.ehdr->e_shoff >= maxsize)
-+ || unlikely (elf->state.elf32.ehdr->e_shoff
-+ + scncnt * sizeof (Elf32_Shdr) > maxsize))
-+ {
-+ free_and_out:
-+ __libelf_seterrno (ELF_E_INVALID_FILE);
-+ free (elf);
-+ return NULL;
-+ }
- elf->state.elf32.shdr =
- (Elf32_Shdr *) ((char *) map_address + offset
- + elf->state.elf32.ehdr->e_shoff);
- if (elf->state.elf32.ehdr->e_phnum)
-- /* Assign a value only if there really is a program
-- header. Otherwise the value remains NULL. */
-- elf->state.elf32.phdr
-- = (Elf32_Phdr *) ((char *) map_address + offset
-- + elf->state.elf32.ehdr->e_phoff);
-+ {
-+ /* Assign a value only if there really is a program
-+ header. Otherwise the value remains NULL. */
-+ if (unlikely (elf->state.elf32.ehdr->e_phoff >= maxsize)
-+ || unlikely (elf->state.elf32.ehdr->e_phoff
-+ + elf->state.elf32.ehdr->e_phnum
-+ * sizeof (Elf32_Phdr) > maxsize))
-+ goto free_and_out;
-+ elf->state.elf32.phdr
-+ = (Elf32_Phdr *) ((char *) map_address + offset
-+ + elf->state.elf32.ehdr->e_phoff);
-+ }
-
- for (size_t cnt = 0; cnt < scncnt; ++cnt)
- {
-@@ -285,8 +316,7 @@ file_read_elf (int fildes, void *map_add
- sizeof (Elf32_Ehdr), offset) != sizeof (Elf32_Ehdr))
- {
- /* We must be able to read the ELF header. */
-- __libelf_seterrno (ELF_E_INVALID_FILE);
-- return NULL;
-+ goto free_and_out;
- }
-
- if (e_ident[EI_DATA] != MY_ELFDATA)
-@@ -340,15 +370,26 @@ file_read_elf (int fildes, void *map_add
- /* We can use the mmapped memory. */
- elf->state.elf64.ehdr =
- (Elf64_Ehdr *) ((char *) map_address + offset);
-+ if (unlikely (elf->state.elf64.ehdr->e_shoff >= maxsize)
-+ || unlikely (elf->state.elf64.ehdr->e_shoff
-+ + scncnt * sizeof (Elf64_Shdr) > maxsize))
-+ goto free_and_out;
- elf->state.elf64.shdr =
- (Elf64_Shdr *) ((char *) map_address + offset
- + elf->state.elf64.ehdr->e_shoff);
- if (elf->state.elf64.ehdr->e_phnum)
-- /* Assign a value only if there really is a program
-- header. Otherwise the value remains NULL. */
-- elf->state.elf64.phdr
-- = (Elf64_Phdr *) ((char *) map_address + offset
-- + elf->state.elf64.ehdr->e_phoff);
-+ {
-+ /* Assign a value only if there really is a program
-+ header. Otherwise the value remains NULL. */
-+ if (unlikely (elf->state.elf64.ehdr->e_phoff >= maxsize)
-+ || unlikely (elf->state.elf64.ehdr->e_phoff
-+ + elf->state.elf64.ehdr->e_phnum
-+ * sizeof (Elf64_Phdr) > maxsize))
-+ goto free_and_out;
-+ elf->state.elf64.phdr
-+ = (Elf64_Phdr *) ((char *) map_address + offset
-+ + elf->state.elf64.ehdr->e_phoff);
-+ }
-
- for (size_t cnt = 0; cnt < scncnt; ++cnt)
- {
-@@ -370,8 +411,7 @@ file_read_elf (int fildes, void *map_add
- sizeof (Elf64_Ehdr), offset) != sizeof (Elf64_Ehdr))
- {
- /* We must be able to read the ELF header. */
-- __libelf_seterrno (ELF_E_INVALID_FILE);
-- return NULL;
-+ goto free_and_out;
- }
-
- if (e_ident[EI_DATA] != MY_ELFDATA)
---- elfutils-0.108/src/elflint.c.jj 2005-05-14 02:22:24.000000000 +0200
-+++ elfutils-0.108/src/elflint.c 2005-05-17 18:02:00.000000000 +0200
-@@ -309,6 +309,8 @@ section_name (Ebl *ebl, int idx)
- return "<invalid>";
-
- shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
-+ if (shdr == NULL)
-+ return "<invalid>";
-
- ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
- if (ret == NULL)
-@@ -1639,19 +1641,26 @@ section [%2d] '%s': hash table section i
- {
- size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
- size_t cnt;
+ Elf32_Word *buf, *end;
if (nchain < symshdr->sh_size / symshdr->sh_entsize)
@@ -1267,7 +1210,19 @@ src/
ERROR (gettext ("\
section [%2d] '%s': hash chain reference %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt - 2 - nbucket);
-@@ -2311,6 +2320,8 @@ phdr[%d]: no note entries defined for th
+@@ -2023,8 +2055,9 @@ section [%2d] '%s' refers in sh_link to
+
+ /* The number of elements in the version symbol table must be the
+ same as the number of symbols. */
+- if (shdr->sh_size / shdr->sh_entsize
+- != symshdr->sh_size / symshdr->sh_entsize)
++ if (shdr->sh_entsize && symshdr->sh_entsize
++ && (shdr->sh_size / shdr->sh_entsize
++ != symshdr->sh_size / symshdr->sh_entsize))
+ ERROR (gettext ("\
+ section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
+ idx, section_name (ebl, idx),
+@@ -2928,6 +2961,8 @@ phdr[%d]: no note entries defined for th
return;
char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz);
@@ -1276,9 +1231,245 @@ src/
/* ELF64 files often use note section entries in the 32-bit format.
The p_align field is set to 8 in case the 64-bit format is used.
-
---- elfutils/src/strip.c
-+++ elfutils/src/strip.c
+--- elfutils-0.114/src/readelf.c
++++ elfutils-0.114/src/readelf.c
+@@ -947,6 +947,7 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
+ GElf_Shdr *symshdr;
+ Elf_Data *symdata;
+ GElf_Sym sym_mem;
++ GElf_Sym *sym;
+ size_t cnt;
+ size_t shstrndx;
+
+@@ -966,6 +967,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+
++ sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
++
+ grpref = (Elf32_Word *) data->d_buf;
+
+ printf ((grpref[0] & GRP_COMDAT)
+@@ -980,8 +983,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
+ data->d_size / sizeof (Elf32_Word) - 1),
+ elf_ndxscn (scn),
+ elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+- elf_strptr (ebl->elf, symshdr->sh_link,
+- gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name)
++ (sym == NULL ? NULL
++ : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
+ ?: gettext ("<INVALID SYMBOL>"),
+ data->d_size / sizeof (Elf32_Word) - 1);
+
+@@ -1135,7 +1138,8 @@ static void
+ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+ {
+ int class = gelf_getclass (ebl->elf);
+- GElf_Shdr glink;
++ GElf_Shdr glink_mem;
++ GElf_Shdr *glink;
+ Elf_Data *data;
+ size_t cnt;
+ size_t shstrndx;
+@@ -1150,6 +1154,11 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn,
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+
++ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
++ if (glink == NULL)
++ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
++ elf_ndxscn (scn));
++
+ printf (ngettext ("\
+ \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
+ "\
+@@ -1159,9 +1168,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn,
+ class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+ shdr->sh_offset,
+ (int) shdr->sh_link,
+- elf_strptr (ebl->elf, shstrndx,
+- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+- &glink)->sh_name));
++ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+ fputs_unlocked (gettext (" Type Value\n"), stdout);
+
+ for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+@@ -1656,7 +1663,8 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
+ unsigned int cnt;
+ Elf32_Word verneed_stridx = 0;
+ Elf32_Word verdef_stridx = 0;
+- GElf_Shdr glink;
++ GElf_Shdr glink_mem;
++ GElf_Shdr *glink;
+ size_t shstrndx;
+
+ /* Get the data of the section. */
+@@ -1701,6 +1709,11 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+
++ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
++ if (glink == NULL)
++ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
++ elf_ndxscn (scn));
++
+ /* Now we can compute the number of entries in the section. */
+ nsyms = data->d_size / (class == ELFCLASS32
+ ? sizeof (Elf32_Sym) : sizeof (Elf64_Sym));
+@@ -1715,9 +1728,7 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
+ shdr->sh_info),
+ (unsigned long int) shdr->sh_info,
+ (unsigned int) shdr->sh_link,
+- elf_strptr (ebl->elf, shstrndx,
+- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+- &glink)->sh_name));
++ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+ fputs_unlocked (class == ELFCLASS32
+ ? gettext ("\
+@@ -1956,7 +1967,13 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+
+- GElf_Shdr glink;
++ GElf_Shdr glink_mem;
++ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
++ &glink_mem);
++ if (glink == NULL)
++ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
++ elf_ndxscn (scn));
++
+ printf (ngettext ("\
+ \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
+ "\
+@@ -1967,9 +1984,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
+ class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+ shdr->sh_offset,
+ (unsigned int) shdr->sh_link,
+- elf_strptr (ebl->elf, shstrndx,
+- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+- &glink)->sh_name));
++ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+ unsigned int offset = 0;
+ for (int cnt = shdr->sh_info; --cnt >= 0; )
+@@ -2022,8 +2037,14 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+
++ GElf_Shdr glink_mem;
++ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
++ &glink_mem);
++ if (glink == NULL)
++ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
++ elf_ndxscn (scn));
++
+ int class = gelf_getclass (ebl->elf);
+- GElf_Shdr glink;
+ printf (ngettext ("\
+ \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
+ "\
+@@ -2035,9 +2056,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
+ class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+ shdr->sh_offset,
+ (unsigned int) shdr->sh_link,
+- elf_strptr (ebl->elf, shstrndx,
+- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+- &glink)->sh_name));
++ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+ unsigned int offset = 0;
+ for (int cnt = shdr->sh_info; --cnt >= 0; )
+@@ -2086,7 +2105,6 @@ static void
+ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+ {
+ int class = gelf_getclass (ebl->elf);
+- GElf_Shdr glink;
+ const char **vername;
+ const char **filename;
+
+@@ -2312,6 +2330,13 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G
+ filename = NULL;
+ }
+
++ GElf_Shdr glink_mem;
++ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
++ &glink_mem);
++ if (glink == NULL)
++ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
++ elf_ndxscn (scn));
++
+ /* Print the header. */
+ printf (ngettext ("\
+ \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
+@@ -2324,9 +2349,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G
+ class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+ shdr->sh_offset,
+ (unsigned int) shdr->sh_link,
+- elf_strptr (ebl->elf, shstrndx,
+- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+- &glink)->sh_name));
++ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+ /* Now we can finally look at the actual contents of this section. */
+ for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+@@ -2402,7 +2425,6 @@ handle_hash (Ebl *ebl)
+ Elf32_Word maxlength = 0;
+ Elf32_Word nsyms = 0;
+ uint64_t nzero_counts = 0;
+- GElf_Shdr glink;
+
+ if (data == NULL)
+ {
+@@ -2411,6 +2433,17 @@ handle_hash (Ebl *ebl)
+ continue;
+ }
+
++ GElf_Shdr glink_mem;
++ GElf_Shdr *glink;
++ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
++ &glink_mem);
++ if (glink == NULL)
++ {
++ error (0, 0, gettext ("invalid sh_link value in section %Zu"),
++ elf_ndxscn (scn));
++ continue;
++ }
++
+ nbucket = ((Elf32_Word *) data->d_buf)[0];
+ nchain = ((Elf32_Word *) data->d_buf)[1];
+ bucket = &((Elf32_Word *) data->d_buf)[2];
+@@ -2428,10 +2461,7 @@ handle_hash (Ebl *ebl)
+ shdr->sh_addr,
+ shdr->sh_offset,
+ (unsigned int) shdr->sh_link,
+- elf_strptr (ebl->elf, shstrndx,
+- gelf_getshdr (elf_getscn (ebl->elf,
+- shdr->sh_link),
+- &glink)->sh_name));
++ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+ lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
+
+@@ -3531,6 +3561,16 @@ print_debug_aranges_section (Ebl *ebl __
+ return;
+ }
+
++ GElf_Shdr glink_mem;
++ GElf_Shdr *glink;
++ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
++ if (glink == NULL)
++ {
++ error (0, 0, gettext ("invalid sh_link value in section %Zu"),
++ elf_ndxscn (scn));
++ return;
++ }
++
+ printf (ngettext ("\
+ \nDWARF section '%s' at offset %#" PRIx64 " contains %zu entry:\n",
+ "\
+--- elfutils-0.114/src/strip.c
++++ elfutils-0.114/src/strip.c
@@ -400,6 +400,7 @@ handle_elf (int fd, Elf *elf, const char
Elf_Data debuglink_crc_data;
bool any_symtab_changes = false;
@@ -1287,7 +1478,7 @@ src/
/* Create the full name of the file. */
if (prefix != NULL)
-@@ -531,6 +532,11 @@ handle_elf (int fd, Elf *elf, const char
+@@ -530,6 +531,11 @@ handle_elf (int fd, Elf *elf, const char
goto fail_close;
}
@@ -1299,7 +1490,7 @@ src/
/* Storage for section information. We leave room for two more
entries since we unconditionally create a section header string
table. Maybe some weird tool created an ELF file without one.
-@@ -552,7 +558,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -551,7 +557,7 @@ handle_elf (int fd, Elf *elf, const char
{
/* This should always be true (i.e., there should not be any
holes in the numbering). */
@@ -1308,7 +1499,7 @@ src/
shdr_info[cnt].scn = scn;
-@@ -565,6 +571,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -564,6 +570,7 @@ handle_elf (int fd, Elf *elf, const char
shdr_info[cnt].shdr.sh_name);
if (shdr_info[cnt].name == NULL)
{
@@ -1316,7 +1507,7 @@ src/
error (0, 0, gettext ("illformed file '%s'"), fname);
goto fail_close;
}
-@@ -574,6 +581,8 @@ handle_elf (int fd, Elf *elf, const char
+@@ -573,6 +580,8 @@ handle_elf (int fd, Elf *elf, const char
/* Remember the shdr.sh_link value. */
shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
@@ -1325,7 +1516,7 @@ src/
/* Sections in files other than relocatable object files which
are not loaded can be freely moved by us. In relocatable
-@@ -586,7 +595,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -585,7 +594,7 @@ handle_elf (int fd, Elf *elf, const char
appropriate reference. */
if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
{
@@ -1334,7 +1525,7 @@ src/
shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
}
else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
-@@ -605,7 +614,12 @@ handle_elf (int fd, Elf *elf, const char
+@@ -602,7 +611,12 @@ handle_elf (int fd, Elf *elf, const char
for (inner = 1;
inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
++inner)
@@ -1348,7 +1539,7 @@ src/
if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
/* If the section group contains only one element and this
-@@ -616,7 +630,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -613,7 +627,7 @@ handle_elf (int fd, Elf *elf, const char
}
else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
{
@@ -1357,7 +1548,7 @@ src/
shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
}
-@@ -624,7 +638,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -621,7 +635,7 @@ handle_elf (int fd, Elf *elf, const char
discarded right away. */
if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
{
@@ -1366,7 +1557,7 @@ src/
if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
{
-@@ -700,10 +714,14 @@ handle_elf (int fd, Elf *elf, const char
+@@ -696,10 +710,14 @@ handle_elf (int fd, Elf *elf, const char
{
/* If a relocation section is marked as being removed make
sure the section it is relocating is removed, too. */
@@ -1385,7 +1576,7 @@ src/
}
if (shdr_info[cnt].idx == 1)
-@@ -733,7 +751,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -725,7 +743,7 @@ handle_elf (int fd, Elf *elf, const char
if (shdr_info[cnt].symtab_idx != 0
&& shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
{
@@ -1394,7 +1585,7 @@ src/
shdr_info[shdr_info[cnt].symtab_idx].data
= elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
-@@ -773,6 +791,9 @@ handle_elf (int fd, Elf *elf, const char
+@@ -765,6 +783,9 @@ handle_elf (int fd, Elf *elf, const char
else if (scnidx == SHN_XINDEX)
scnidx = xndx;
@@ -1404,7 +1595,7 @@ src/
if (shdr_info[scnidx].idx == 0)
{
/* Mark this section as used. */
-@@ -804,11 +825,15 @@ handle_elf (int fd, Elf *elf, const char
+@@ -796,11 +817,15 @@ handle_elf (int fd, Elf *elf, const char
}
/* Handle references through sh_info. */
@@ -1424,7 +1615,7 @@ src/
}
/* Mark the section as investigated. */
-@@ -911,7 +936,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -900,7 +925,7 @@ handle_elf (int fd, Elf *elf, const char
error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
elf_errmsg (-1));
@@ -1433,7 +1624,7 @@ src/
/* Add this name to the section header string table. */
shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
-@@ -951,7 +976,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -937,7 +962,7 @@ handle_elf (int fd, Elf *elf, const char
error (EXIT_FAILURE, 0,
gettext ("while create section header section: %s"),
elf_errmsg (-1));
@@ -1442,7 +1633,7 @@ src/
shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
if (shdr_info[cnt].data == NULL)
-@@ -982,7 +1007,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -968,7 +993,7 @@ handle_elf (int fd, Elf *elf, const char
}
/* Index of the section header table in the shdr_info array. */
@@ -1451,7 +1642,7 @@ src/
/* Add the section header string table section name. */
shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
-@@ -1007,7 +1032,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -993,7 +1018,7 @@ handle_elf (int fd, Elf *elf, const char
error (EXIT_FAILURE, 0,
gettext ("while create section header section: %s"),
elf_errmsg (-1));
@@ -1460,7 +1651,7 @@ src/
/* Finalize the string table and fill in the correct indices in the
section headers. */
-@@ -1097,21 +1122,21 @@ handle_elf (int fd, Elf *elf, const char
+@@ -1083,21 +1108,21 @@ handle_elf (int fd, Elf *elf, const char
shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
NULL);
@@ -1487,7 +1678,7 @@ src/
}
shdr_info[cnt].newsymidx
-@@ -1165,7 +1190,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -1151,7 +1176,7 @@ handle_elf (int fd, Elf *elf, const char
sec = shdr_info[sym->st_shndx].idx;
else
{
@@ -1496,7 +1687,7 @@ src/
sec = shdr_info[xshndx].idx;
}
-@@ -1186,7 +1211,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -1172,7 +1197,7 @@ handle_elf (int fd, Elf *elf, const char
nxshndx = sec;
}
@@ -1505,7 +1696,7 @@ src/
if ((inner != destidx || nshndx != sym->st_shndx
|| (shndxdata != NULL && nxshndx != xshndx))
-@@ -1209,7 +1234,7 @@ handle_elf (int fd, Elf *elf, const char
+@@ -1195,7 +1220,7 @@ handle_elf (int fd, Elf *elf, const char
else
/* This is a section symbol for a section which has
been removed. */
@@ -1514,7 +1705,7 @@ src/
}
if (destidx != inner)
-@@ -1373,11 +1398,11 @@ handle_elf (int fd, Elf *elf, const char
+@@ -1359,11 +1384,11 @@ handle_elf (int fd, Elf *elf, const char
{
GElf_Sym sym_mem;
GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
@@ -1528,7 +1719,7 @@ src/
size_t hidx = elf_hash (name) % nbucket;
if (bucket[hidx] == 0)
-@@ -1396,8 +1421,8 @@ handle_elf (int fd, Elf *elf, const char
+@@ -1382,8 +1407,8 @@ handle_elf (int fd, Elf *elf, const char
else
{
/* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */
@@ -1539,7 +1730,7 @@ src/
Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
-@@ -1430,11 +1455,11 @@ handle_elf (int fd, Elf *elf, const char
+@@ -1416,11 +1441,11 @@ handle_elf (int fd, Elf *elf, const char
{
GElf_Sym sym_mem;
GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
@@ -1553,237 +1744,3 @@ src/
size_t hidx = elf_hash (name) % nbucket;
if (bucket[hidx] == 0)
---- elfutils/src/readelf.c
-+++ elfutils/src/readelf.c
-@@ -947,6 +947,7 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
- GElf_Shdr *symshdr;
- Elf_Data *symdata;
- GElf_Sym sym_mem;
-+ GElf_Sym *sym;
- size_t cnt;
- size_t shstrndx;
-
-@@ -966,6 +967,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
- error (EXIT_FAILURE, 0,
- gettext ("cannot get section header string table index"));
-
-+ sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
-+
- grpref = (Elf32_Word *) data->d_buf;
-
- printf ((grpref[0] & GRP_COMDAT)
-@@ -980,8 +983,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
- data->d_size / sizeof (Elf32_Word) - 1),
- elf_ndxscn (scn),
- elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
-- elf_strptr (ebl->elf, symshdr->sh_link,
-- gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name)
-+ (sym == NULL ? NULL
-+ : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
- ?: gettext ("<INVALID SYMBOL>"),
- data->d_size / sizeof (Elf32_Word) - 1);
-
-@@ -1135,7 +1138,8 @@ static void
- handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
- {
- int class = gelf_getclass (ebl->elf);
-- GElf_Shdr glink;
-+ GElf_Shdr glink_mem;
-+ GElf_Shdr *glink;
- Elf_Data *data;
- size_t cnt;
- size_t shstrndx;
-@@ -1150,6 +1154,11 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn,
- error (EXIT_FAILURE, 0,
- gettext ("cannot get section header string table index"));
-
-+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
-+ if (glink == NULL)
-+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
-+ elf_ndxscn (scn));
-+
- printf (ngettext ("\
- \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
- "\
-@@ -1159,9 +1168,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn,
- class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
- shdr->sh_offset,
- (int) shdr->sh_link,
-- elf_strptr (ebl->elf, shstrndx,
-- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
-- &glink)->sh_name));
-+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
- fputs_unlocked (gettext (" Type Value\n"), stdout);
-
- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
-@@ -1656,7 +1663,8 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
- unsigned int cnt;
- Elf32_Word verneed_stridx = 0;
- Elf32_Word verdef_stridx = 0;
-- GElf_Shdr glink;
-+ GElf_Shdr glink_mem;
-+ GElf_Shdr *glink;
- size_t shstrndx;
-
- /* Get the data of the section. */
-@@ -1701,6 +1709,11 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
- error (EXIT_FAILURE, 0,
- gettext ("cannot get section header string table index"));
-
-+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
-+ if (glink == NULL)
-+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
-+ elf_ndxscn (scn));
-+
- /* Now we can compute the number of entries in the section. */
- nsyms = data->d_size / (class == ELFCLASS32
- ? sizeof (Elf32_Sym) : sizeof (Elf64_Sym));
-@@ -1715,9 +1728,7 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
- shdr->sh_info),
- (unsigned long int) shdr->sh_info,
- (unsigned int) shdr->sh_link,
-- elf_strptr (ebl->elf, shstrndx,
-- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
-- &glink)->sh_name));
-+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
-
- fputs_unlocked (class == ELFCLASS32
- ? gettext ("\
-@@ -1945,7 +1956,8 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
- {
- Elf_Data *data;
- int class = gelf_getclass (ebl->elf);
-- GElf_Shdr glink;
-+ GElf_Shdr glink_mem;
-+ GElf_Shdr *glink;
- int cnt;
- unsigned int offset;
- size_t shstrndx;
-@@ -1960,6 +1972,11 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
- error (EXIT_FAILURE, 0,
- gettext ("cannot get section header string table index"));
-
-+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
-+ if (glink == NULL)
-+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
-+ elf_ndxscn (scn));
-+
- printf (ngettext ("\
- \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
- "\
-@@ -1970,9 +1987,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
- class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
- shdr->sh_offset,
- (unsigned int) shdr->sh_link,
-- elf_strptr (ebl->elf, shstrndx,
-- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
-- &glink)->sh_name));
-+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
-
- offset = 0;
- for (cnt = shdr->sh_info; --cnt >= 0; )
-@@ -2022,7 +2037,8 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
- {
- Elf_Data *data;
- int class = gelf_getclass (ebl->elf);
-- GElf_Shdr glink;
-+ GElf_Shdr glink_mem;
-+ GElf_Shdr *glink;
- int cnt;
- unsigned int offset;
- size_t shstrndx;
-@@ -2037,6 +2053,11 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
- error (EXIT_FAILURE, 0,
- gettext ("cannot get section header string table index"));
-
-+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
-+ if (glink == NULL)
-+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
-+ elf_ndxscn (scn));
-+
- printf (ngettext ("\
- \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
- "\
-@@ -2048,9 +2069,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
- class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
- shdr->sh_offset,
- (unsigned int) shdr->sh_link,
-- elf_strptr (ebl->elf, shstrndx,
-- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
-- &glink)->sh_name));
-+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
-
- offset = 0;
- for (cnt = shdr->sh_info; --cnt >= 0; )
-@@ -2106,7 +2125,8 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G
- Elf_Data *data;
- int class = gelf_getclass (ebl->elf);
- Elf_Scn *verscn;
-- GElf_Shdr glink;
-+ GElf_Shdr glink_mem;
-+ GElf_Shdr *glink;
- Elf_Scn *defscn;
- Elf_Scn *needscn;
- const char **vername;
-@@ -2125,6 +2145,11 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G
- error (EXIT_FAILURE, 0,
- gettext ("cannot get section header string table index"));
-
-+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
-+ if (glink == NULL)
-+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
-+ elf_ndxscn (scn));
-+
- /* We have to find the version definition section and extract the
- version names. */
- defscn = NULL;
-@@ -2347,9 +2372,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G
- class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
- shdr->sh_offset,
- (unsigned int) shdr->sh_link,
-- elf_strptr (ebl->elf, shstrndx,
-- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
-- &glink)->sh_name));
-+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
-
- /* Now we can finally look at the actual contents of this section. */
- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
-@@ -2425,7 +2448,8 @@ handle_hash (Ebl *ebl)
- Elf32_Word maxlength = 0;
- Elf32_Word nsyms = 0;
- uint64_t nzero_counts = 0;
-- GElf_Shdr glink;
-+ GElf_Shdr glink_mem;
-+ GElf_Shdr *glink;
-
- if (data == NULL)
- {
-@@ -2434,6 +2458,16 @@ handle_hash (Ebl *ebl)
- continue;
- }
-
-+
-+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
-+ &glink_mem);
-+ if (glink == NULL)
-+ {
-+ error (0, 0, gettext ("invalid sh_link value in section %Zu"),
-+ elf_ndxscn (scn));
-+ continue;
-+ }
-+
- nbucket = ((Elf32_Word *) data->d_buf)[0];
- nchain = ((Elf32_Word *) data->d_buf)[1];
- bucket = &((Elf32_Word *) data->d_buf)[2];
-@@ -2451,10 +2485,7 @@ handle_hash (Ebl *ebl)
- shdr->sh_addr,
- shdr->sh_offset,
- (unsigned int) shdr->sh_link,
-- elf_strptr (ebl->elf, shstrndx,
-- gelf_getshdr (elf_getscn (ebl->elf,
-- shdr->sh_link),
-- &glink)->sh_name));
-+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
-
- lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
-
diff --git a/elfutils.spec b/elfutils.spec
index 19705e25..6da4d98a 100644
--- a/elfutils.spec
+++ b/elfutils.spec
@@ -1,13 +1,14 @@
Name: elfutils
-Version: 0.108
-Release: alt3
+Version: 0.114
+Release: alt1
Summary: A collection of utilities and DSOs to handle compiled objects
License: OSL
Group: Development/C
Source: %name-%version.tar.bz2
Patch1: %name-rh-portability.patch
-Patch2: %name-0.108-rh-robustify.patch
+Patch2: %name-0.114-rh-robustify.patch
+Patch3: %name-0.114-alt-makefile.patch
Requires: libelf = %version-%release
%define gpl 0
@@ -75,6 +76,7 @@ object file format, so you can see the different sections of an ELF file.
%setup -q
%patch1 -p1
%patch2 -p1
+%patch3 -p1
%__subst -p 's/ -Werror / /' tests/Makefile*
%build
@@ -89,6 +91,7 @@ popd
%install
%__mkdir_p $RPM_BUILD_ROOT%prefix
%makeinstall -C %buildtarget
+#%__install -pm644 %buildtarget/src/libld_elf_*.so %buildroot%_libdir/
%post -p %post_ldconfig
%postun -p %postun_ldconfig
@@ -102,18 +105,22 @@ popd
%doc fake-src/FULL
%endif
%_bindir/eu-addr2line
+%_bindir/eu-elfcmp
%_bindir/eu-elflint
%_bindir/eu-findtextrel
%_bindir/eu-nm
+%_bindir/eu-ranlib
%_bindir/eu-readelf
%_bindir/eu-size
%_bindir/eu-strip
%if !%gpl
-%_bindir/eu-ld
+%exclude %_bindir/eu-ld
+%exclude %_bindir/eu-objdump
%_libdir/libasm-*.so
%_libdir/libdw-*.so
%_libdir/libasm*.so.*
%_libdir/libdw*.so.*
+#%_libdir/libld_elf_*.so
%_libdir/elfutils
%endif
@@ -136,6 +143,9 @@ popd
%_includedir/nlist.h
%changelog
+* Sun Sep 04 2005 Dmitry V. Levin <ldv@altlinux.org> 0.114-alt1
+- Updated to 0.114.
+
* Thu Jun 16 2005 Dmitry V. Levin <ldv@altlinux.org> 0.108-alt3
- Applied additional robustification of eu-strip and eu-readelf
from RH's elfutils-0.108-5.
diff --git a/elfutils/ChangeLog b/elfutils/ChangeLog
index 1e83f334..9a7850aa 100644
--- a/elfutils/ChangeLog
+++ b/elfutils/ChangeLog
@@ -1,3 +1,28 @@
+2005-08-06 Ulrich Drepper <drepper@redhat.com>
+
+ * configure.ac: Add --enable-gprof option.
+
+2005-07-27 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am (all_SUBDIRS): Put libdwfl before libdw.
+
+2005-07-21 Roland McGrath <roland@redhat.com>
+
+ * configure.ac: Take --enable-libebl-subdir=DIR to set LIBEBL_SUBDIR.
+
+2005-06-01 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am (all_SUBDIRS): Add libdwfl.
+ * configure.ac: Write libdwfl/Makefile.
+
+2005-05-19 Roland McGrath <roland@redhat.com>
+
+ * configure.ac [AH_BOTTOM] (INTDECL, _INTDECL): New macros.
+
+2005-05-10 Ulrich Drepper <drepper@redhat.com>
+
+ * configure.ac: Define MODVERSION in config.h.
+
2005-02-22 Ulrich Drepper <drepper@redhat.com>
* Makefile.am (all_SUBDIRS): Don't add doc subdir for now.
diff --git a/elfutils/Makefile.am b/elfutils/Makefile.am
index 1637d3ab..ef24c416 100644
--- a/elfutils/Makefile.am
+++ b/elfutils/Makefile.am
@@ -20,7 +20,7 @@ ACLOCAL_AMFLAGS = -I m4
mini_SUBDIRS = config m4 lib libelf libelf-po
# Add doc back when we have some real content.
-all_SUBDIRS = libebl libdw libcpu libasm src po tests
+all_SUBDIRS = libebl libdwfl libdw libcpu libasm src po tests
SUBDIRS = $(mini_SUBDIRS) $(all_SUBDIRS)
EXTRA_DIST = elfutils.spec GPG-KEY NOTES COPYING.GPL
diff --git a/elfutils/Makefile.in b/elfutils/Makefile.in
index d48b4c33..41a9b790 100644
--- a/elfutils/Makefile.in
+++ b/elfutils/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -80,6 +80,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -93,6 +95,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -101,12 +105,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -171,7 +177,7 @@ target_alias = @target_alias@
ACLOCAL_AMFLAGS = -I m4
mini_SUBDIRS = config m4 lib libelf libelf-po
# Add doc back when we have some real content.
-all_SUBDIRS = libebl libdw libcpu libasm src po tests
+all_SUBDIRS = libebl libdwfl libdw libcpu libasm src po tests
SUBDIRS = $(mini_SUBDIRS) $(all_SUBDIRS)
EXTRA_DIST = elfutils.spec GPG-KEY NOTES COPYING.GPL
all: config.h
diff --git a/elfutils/NEWS b/elfutils/NEWS
index dfc32569..a15e1f12 100644
--- a/elfutils/NEWS
+++ b/elfutils/NEWS
@@ -1,3 +1,63 @@
+Version 0.114:
+
+libelf: new function elf_getaroff
+
+libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_instances.
+
+libdwfl: New functions dwfl_report_offline, dwfl_offline_section_address,
+ dwfl_linux_kernel_report_offline.
+
+ranlib: new program
+
+Version 0.113:
+
+elflint: relax a bit. Allow version definitions for defined symbols against
+DSO versions also for symbols in nobits sections. Allow .rodata section
+to have STRINGS and MERGE flag set.
+
+strip: add some more compatibility with binutils.
+
+Version 0.112:
+
+elfcmp: some more relaxation.
+
+elflint: many more tests, especially regarding to symbol versioning.
+
+libelf: Add elfXX_offscn and gelf_offscn.
+
+libasm: asm_begin interface changes.
+
+libebl: Add three new interfaces to directly access machine, class, and
+data encoding information.
+
+objdump: New program. Just the beginning.
+
+Version 0.111:
+
+libdw: now contains all of libdwfl. The latter is not installed anymore.
+
+elfcmp: little usability tweak, name and index of differing section is printed.
+
+Version 0.110:
+
+libelf: fix a number of problems with elf_update
+
+elfcmp: fix a few bugs. Compare gaps.
+
+Fix a few PLT problems and mudflap build issues.
+
+libebl: Don't expose Ebl structure definition in libebl.h. It's now private.
+
+Version 0.109:
+
+libebl: Check for matching modules.
+
+elflint: Check that copy relocations only happen for OBJECT or NOTYPE symbols.
+
+elfcmp: New program.
+
+libdwfl: New library.
+
Version 0.108:
strip: fix bug introduced in last change
diff --git a/elfutils/THANKS b/elfutils/THANKS
index 543436c2..3ee88d16 100644
--- a/elfutils/THANKS
+++ b/elfutils/THANKS
@@ -3,3 +3,4 @@ At least the following have submitted valuable patches:
Jeff Johnson building. rpm wrestling
Alexander Larsson separate debug info
Jakub Jelinek bug fixes, testing
+Roland McGrath lots of libdw{,fl} hacking
diff --git a/elfutils/TODO b/elfutils/TODO
index bf4a0333..318da823 100644
--- a/elfutils/TODO
+++ b/elfutils/TODO
@@ -1,7 +1,7 @@
ToDo list for elfutils -*-outline-*-
----------------------
-Time-stamp: <2003-08-07 12:52:49 drepper>
+Time-stamp: <2005-08-03 20:38:01 drepper>
* mkinstalldirs
@@ -105,10 +105,6 @@ Time-stamp: <2003-08-07 12:52:49 drepper>
1st GOT entry == _DYNAMIC
- if TEXTREL check whether any relocation touches RO segment
-
- if TEXTREL not set check that no relocation touches RO segment
-
check versioning info:
always BASE in verdef
@@ -116,14 +112,6 @@ Time-stamp: <2003-08-07 12:52:49 drepper>
check whether any relocation is for a merge-able section
-** possibly missing tests
-
- at most one extended section index table for a symtab
-
- no extended section index table != ET_REL
-
- no extended section index table for SHT_DYNSYM
-
** relax
prelink generated files
diff --git a/elfutils/aclocal.m4 b/elfutils/aclocal.m4
index 631562f0..3eb556f9 100644
--- a/elfutils/aclocal.m4
+++ b/elfutils/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.9.5 -*- Autoconf -*-
+# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005 Free Software Foundation, Inc.
@@ -28,7 +28,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
- [AM_AUTOMAKE_VERSION([1.9.5])])
+ [AM_AUTOMAKE_VERSION([1.9.6])])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
diff --git a/elfutils/config.h.in b/elfutils/config.h.in
index 7afe12c6..be063abf 100644
--- a/elfutils/config.h.in
+++ b/elfutils/config.h.in
@@ -1,8 +1,14 @@
/* config.h.in. Generated from configure.ac by autoheader. */
+/* $libdir subdirectory containing libebl modules. */
+#undef LIBEBL_SUBDIR
+
/* Directory to place translation files in. */
#undef LOCALEDIR
+/* Identifier for modules in the build. */
+#undef MODVERSION
+
/* Define to 32 or 64 if a specific implementation is wanted. */
#undef NATIVE_ELF
@@ -124,8 +130,12 @@
# define INTDEF(name) _INTDEF(name)
# define _INTDEF(name) \
extern __typeof__ (name) __##name##_internal __attribute__ ((alias (#name)));
+# define INTDECL(name) _INTDECL(name)
+# define _INTDECL(name) \
+ extern __typeof__ (name) __##name##_internal attribute_hidden;
#else
# define INTUSE(name) name
# define INTDEF(name) /* empty */
+# define INTDECL(name) /* empty */
#endif
diff --git a/elfutils/config/ChangeLog b/elfutils/config/ChangeLog
index 79a78e99..43d44ac9 100644
--- a/elfutils/config/ChangeLog
+++ b/elfutils/config/ChangeLog
@@ -1,3 +1,15 @@
+2005-08-13 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am ($(srcdir)/elfutils.spec.in): Add missing $.
+
+2005-07-28 Roland McGrath <roland@redhat.com>
+
+ * elfutils.spec.in: Remove libdwfl.so from package.
+
+2005-07-21 Ulrich Drepper <drepper@redhat.com>
+
+ * elfutils.spec.in: Distribute eu-elfcmp.
+
2005-04-01 Ulrich Drepper <drepper@redhat.com>
* elfutils.spec.in: Distribute eu-addr2line.
diff --git a/elfutils/config/Makefile.am b/elfutils/config/Makefile.am
index 45a78deb..9c1ad572 100644
--- a/elfutils/config/Makefile.am
+++ b/elfutils/config/Makefile.am
@@ -23,7 +23,7 @@ $(srcdir)/elfutils.spec.in: $(top_srcdir)/NEWS
date +'* %a %b %e %Y' | tr '[\n]' '[ ]' > $$tmpname; \
getent passwd "$$(whoami)" | \
awk 'BEGIN {FS=":"} { printf $$5; exit 0}' >> $$tmpname; \
- echo -n " <$(whoami)@redhat.com> " >> $$tmpname; \
+ echo -n " <$$(whoami)@redhat.com> " >> $$tmpname; \
sed 's/Version \(.*\):$$/\1-1/;q' $(top_srcdir)/NEWS >> $$tmpname; \
sed '2,/^Version /p;d' $(top_srcdir)/NEWS | \
head -n -1 | \
diff --git a/elfutils/config/Makefile.in b/elfutils/config/Makefile.in
index 779c7b99..5388cf9c 100644
--- a/elfutils/config/Makefile.in
+++ b/elfutils/config/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -58,6 +58,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -71,6 +73,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -79,12 +83,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -303,7 +309,7 @@ $(srcdir)/elfutils.spec.in: $(top_srcdir)/NEWS
date +'* %a %b %e %Y' | tr '[\n]' '[ ]' > $$tmpname; \
getent passwd "$$(whoami)" | \
awk 'BEGIN {FS=":"} { printf $$5; exit 0}' >> $$tmpname; \
- echo -n " <$(whoami)@redhat.com> " >> $$tmpname; \
+ echo -n " <$$(whoami)@redhat.com> " >> $$tmpname; \
sed 's/Version \(.*\):$$/\1-1/;q' $(top_srcdir)/NEWS >> $$tmpname; \
sed '2,/^Version /p;d' $(top_srcdir)/NEWS | \
head -n -1 | \
diff --git a/elfutils/config/depcomp b/elfutils/config/depcomp
index 368e3be9..368e3be9 100755..100644
--- a/elfutils/config/depcomp
+++ b/elfutils/config/depcomp
diff --git a/elfutils/config/elfutils.spec.in b/elfutils/config/elfutils.spec.in
index 8dff0efe..bfeda144 100644
--- a/elfutils/config/elfutils.spec.in
+++ b/elfutils/config/elfutils.spec.in
@@ -109,6 +109,8 @@ chmod +x ${RPM_BUILD_ROOT}%{_prefix}/%{_lib}/elfutils/lib*.so*
rm -f .%{_bindir}/eu-ld
rm -f .%{_includedir}/elfutils/libasm.h
rm -f .%{_libdir}/libasm-%{version}.so
+ rm -f .%{_libdir}/libasm.so.*
+ rm -f .%{_libdir}/libasm.so
rm -f .%{_libdir}/libasm.a
}
%endif
@@ -140,12 +142,13 @@ rm -rf ${RPM_BUILD_ROOT}
%{_bindir}/eu-strip
%{_bindir}/eu-findtextrel
%{_bindir}/eu-addr2line
+%{_bindir}/eu-elfcmp
%if !%{fake}
#%{_bindir}/eu-ld
#%{_libdir}/libasm-%{version}.so
%{_libdir}/libdw-%{version}.so
-#%{_libdir}/libasm*.so.*
-%{_libdir}/libdw*.so.*
+#%{_libdir}/libasm.so.*
+%{_libdir}/libdw.so.*
%dir %{_libdir}/elfutils
%{_libdir}/elfutils/lib*.so
%endif
@@ -158,6 +161,7 @@ rm -rf ${RPM_BUILD_ROOT}
%if !%{fake}
%{_includedir}/elfutils/libebl.h
%{_includedir}/elfutils/libdw.h
+%{_includedir}/elfutils/libdwfl.h
#%{_libdir}/libasm.a
%{_libdir}/libebl.a
%{_libdir}/libdw.a
@@ -168,7 +172,7 @@ rm -rf ${RPM_BUILD_ROOT}
%files libelf
%defattr(-,root,root)
%{_libdir}/libelf-%{version}.so
-%{_libdir}/libelf*.so.*
+%{_libdir}/libelf.so.*
%files libelf-devel
%defattr(-,root,root)
@@ -179,6 +183,65 @@ rm -rf ${RPM_BUILD_ROOT}
%{_libdir}/libelf.so
%changelog
+* Wed Aug 24 2005 Ulrich Drepper <drepper@redhat.com> 0.114-1
+- libelf: new function elf_getaroff
+- libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_inst
+ances.
+- libdwfl: New functions dwfl_report_offline, dwfl_offline_section_addre
+ss, dwfl_linux_kernel_report_offline.
+- ranlib: new program
+
+* Mon Aug 15 2005 Ulrich Drepper <drepper@redhat.com> 0.114-1
+- libelf: new function elf_getaroff
+- ranlib: new program
+
+* Wed Aug 10 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections. Allow .rodata
+sectionto have STRINGS and MERGE flag set.
+- strip: add some more compatibility with binutils.
+
+* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections. Allow .rodata
+sectionto have STRINGS and MERGE flag set.
+
+* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections.
+
+* Fri Aug 5 2005 Ulrich Drepper <@redhat.com> 0.112-1
+- elfcmp: some more relaxation.
+- elflint: many more tests, especially regarding to symbol versioning.
+- libelf: Add elfXX_offscn and gelf_offscn.
+- libasm: asm_begin interface changes.
+- libebl: Add three new interfaces to directly access machine, class, an
+ddata encoding information.
+- objdump: New program. Just the beginning.
+
+* Thu Jul 28 2005 Ulrich Drepper <@redhat.com> 0.111-1
+- libdw: now contains all of libdwfl. The latter is not installed anymore.
+- elfcmp: little usability tweak, name and index of differing section is
+ printed.
+
+* Sun Jul 24 2005 Ulrich Drepper <@redhat.com> 0.110-1
+- libelf: fix a numbe rof problems with elf_update
+- elfcmp: fix a few bugs. Compare gaps.
+- Fix a few PLT problems and mudflap build issues.
+- libebl: Don't expose Ebl structure definition in libebl.h. It's now p
+rivate.
+
+* Thu Jul 21 2005 Ulrich Drepper <@redhat.com> 0.109-1
+- libebl: Check for matching modules.
+- elflint: Check that copy relocations only happen for OBJECT or NOTYPE
+symbols.
+- elfcmp: New program.
+- libdwfl: New library.
+
+* Mon May 9 2005 Ulrich Drepper <@redhat.com> 0.108-1
+- strip: fix bug introduced in last change
+- libdw: records returned by dwarf_getsrclines are now sorted by address
+
* Sun May 8 2005 Ulrich Drepper <@redhat.com> 0.108-1
- strip: fix bug introduced in last change
diff --git a/elfutils/config/install-sh b/elfutils/config/install-sh
index 398a88e1..398a88e1 100755..100644
--- a/elfutils/config/install-sh
+++ b/elfutils/config/install-sh
diff --git a/elfutils/config/missing b/elfutils/config/missing
index dd583709..dd583709 100755..100644
--- a/elfutils/config/missing
+++ b/elfutils/config/missing
diff --git a/elfutils/config/mkinstalldirs b/elfutils/config/mkinstalldirs
index e1666cfb..4fbbc3e8 100755..100644
--- a/elfutils/config/mkinstalldirs
+++ b/elfutils/config/mkinstalldirs
@@ -4,7 +4,7 @@
# Created: 1993-05-16
# Public domain
-# $Id: mkinstalldirs,v 1.1 2004/01/18 07:34:34 drepper Exp $
+# $Id: mkinstalldirs,v 1.1.1.1 2003/08/12 06:44:46 drepper Exp $
errstatus=0
dirmode=""
diff --git a/elfutils/configure b/elfutils/configure
index 3ef36793..1fec1206 100755
--- a/elfutils/configure
+++ b/elfutils/configure
@@ -1,7 +1,6 @@
#! /bin/sh
-# From configure.ac Revision: 1.45 .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for Red Hat elfutils 0.108.
+# Generated by GNU Autoconf 2.59 for Red Hat elfutils 0.114.
#
# Report bugs to <http://bugzilla.redhat.com/bugzilla/>.
#
@@ -272,12 +271,12 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='Red Hat elfutils'
PACKAGE_TARNAME='elfutils'
-PACKAGE_VERSION='0.108'
-PACKAGE_STRING='Red Hat elfutils 0.108'
+PACKAGE_VERSION='0.114'
+PACKAGE_STRING='Red Hat elfutils 0.114'
PACKAGE_BUGREPORT='http://bugzilla.redhat.com/bugzilla/'
ac_unique_file="libelf/libelf.h"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB YACC LEX LEXLIB LEX_OUTPUT_ROOT LOCALEDIR DATADIRNAME NATIVE_LD_TRUE NATIVE_LD_FALSE base_cpu MUDFLAP_TRUE MUDFLAP_FALSE USE_NLS MKINSTALLDIRS MSGFMT GMSGFMT XGETTEXT MSGMERGE LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MODVERSION build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB YACC LEX LEXLIB LEX_OUTPUT_ROOT LOCALEDIR DATADIRNAME NATIVE_LD_TRUE NATIVE_LD_FALSE base_cpu MUDFLAP_TRUE MUDFLAP_FALSE GPROF_TRUE GPROF_FALSE BUILD_STATIC_TRUE BUILD_STATIC_FALSE LIBEBL_SUBDIR USE_NLS MKINSTALLDIRS MSGFMT GMSGFMT XGETTEXT MSGMERGE LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -742,7 +741,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Red Hat elfutils 0.108 to adapt to many kinds of systems.
+\`configure' configures Red Hat elfutils 0.114 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -808,7 +807,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Red Hat elfutils 0.108:";;
+ short | recursive ) echo "Configuration of Red Hat elfutils 0.114:";;
esac
cat <<\_ACEOF
@@ -821,6 +820,9 @@ Optional Features:
--disable-largefile omit support for large files
--disable-generic do not build generic linker
--enable-mudflap build binaries with mudflap instrumentation
+ --enable-gprof build binaries with gprof support
+ --enable-libebl-subdir=DIR
+ install libebl_CPU modules in $(libdir)/DIR
Some influential environment variables:
CC C compiler command
@@ -929,7 +931,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-Red Hat elfutils configure 0.108
+Red Hat elfutils configure 0.114
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@@ -945,7 +947,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Red Hat elfutils $as_me 0.108, which was
+It was created by Red Hat elfutils $as_me 0.114, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1312,7 +1314,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
-
am__api_version="1.9"
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -1595,7 +1596,7 @@ fi
# Define the identity of the package.
PACKAGE='elfutils'
- VERSION='0.108'
+ VERSION='0.114'
cat >>confdefs.h <<_ACEOF
@@ -1726,6 +1727,15 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+MODVERSION="Build on $(hostname) $(date +%FT%R:%S%z)"
+
+cat >>confdefs.h <<_ACEOF
+#define MODVERSION "$MODVERSION"
+_ACEOF
+
+
+
+
ac_config_files="$ac_config_files Makefile"
@@ -3864,6 +3874,52 @@ else
fi
+# Enable gprof suport.
+# Check whether --enable-gprof or --disable-gprof was given.
+if test "${enable_gprof+set}" = set; then
+ enableval="$enable_gprof"
+ use_gprof=yes
+else
+ use_gprof=no
+fi;
+if test "$use_gprof" = yes; then
+ CFLAGS="$CFLAGS -pg"
+ LDFLAGS="$LDFLAGS -pg"
+fi
+
+
+if test "$use_gprof" = yes; then
+ GPROF_TRUE=
+ GPROF_FALSE='#'
+else
+ GPROF_TRUE='#'
+ GPROF_FALSE=
+fi
+
+
+
+if test "$use_mudflap" = yes -o "$use_gprof" = yes; then
+ BUILD_STATIC_TRUE=
+ BUILD_STATIC_FALSE='#'
+else
+ BUILD_STATIC_TRUE='#'
+ BUILD_STATIC_FALSE=
+fi
+
+
+LIBEBL_SUBDIR="$PACKAGE"
+# Check whether --enable-libebl-subdir or --disable-libebl-subdir was given.
+if test "${enable_libebl_subdir+set}" = set; then
+ enableval="$enable_libebl_subdir"
+ LIBEBL_SUBDIR="$enable_libebl_subdir"
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define LIBEBL_SUBDIR "$LIBEBL_SUBDIR"
+_ACEOF
+
+
+
@@ -3879,6 +3935,9 @@ fi
ac_config_files="$ac_config_files libdw/Makefile"
+ ac_config_files="$ac_config_files libdwfl/Makefile"
+
+
ac_config_files="$ac_config_files libcpu/Makefile"
@@ -4213,6 +4272,20 @@ echo "$as_me: error: conditional \"MUDFLAP\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${GPROF_TRUE}" && test -z "${GPROF_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"GPROF\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"GPROF\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${BUILD_STATIC_TRUE}" && test -z "${BUILD_STATIC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"BUILD_STATIC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"BUILD_STATIC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
: ${CONFIG_STATUS=./config.status}
ac_clean_files_save=$ac_clean_files
@@ -4484,7 +4557,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
-This file was extended by Red Hat elfutils $as_me 0.108, which was
+This file was extended by Red Hat elfutils $as_me 0.114, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -4547,7 +4620,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-Red Hat elfutils config.status 0.108
+Red Hat elfutils config.status 0.114
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
@@ -4673,6 +4746,7 @@ do
"libelf-po/Makefile.in" ) CONFIG_FILES="$CONFIG_FILES libelf-po/Makefile.in" ;;
"libebl/Makefile" ) CONFIG_FILES="$CONFIG_FILES libebl/Makefile" ;;
"libdw/Makefile" ) CONFIG_FILES="$CONFIG_FILES libdw/Makefile" ;;
+ "libdwfl/Makefile" ) CONFIG_FILES="$CONFIG_FILES libdwfl/Makefile" ;;
"libcpu/Makefile" ) CONFIG_FILES="$CONFIG_FILES libcpu/Makefile" ;;
"libasm/Makefile" ) CONFIG_FILES="$CONFIG_FILES libasm/Makefile" ;;
"src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
@@ -4788,6 +4862,7 @@ s,@am__leading_dot@,$am__leading_dot,;t t
s,@AMTAR@,$AMTAR,;t t
s,@am__tar@,$am__tar,;t t
s,@am__untar@,$am__untar,;t t
+s,@MODVERSION@,$MODVERSION,;t t
s,@build@,$build,;t t
s,@build_cpu@,$build_cpu,;t t
s,@build_vendor@,$build_vendor,;t t
@@ -4825,6 +4900,11 @@ s,@NATIVE_LD_FALSE@,$NATIVE_LD_FALSE,;t t
s,@base_cpu@,$base_cpu,;t t
s,@MUDFLAP_TRUE@,$MUDFLAP_TRUE,;t t
s,@MUDFLAP_FALSE@,$MUDFLAP_FALSE,;t t
+s,@GPROF_TRUE@,$GPROF_TRUE,;t t
+s,@GPROF_FALSE@,$GPROF_FALSE,;t t
+s,@BUILD_STATIC_TRUE@,$BUILD_STATIC_TRUE,;t t
+s,@BUILD_STATIC_FALSE@,$BUILD_STATIC_FALSE,;t t
+s,@LIBEBL_SUBDIR@,$LIBEBL_SUBDIR,;t t
s,@USE_NLS@,$USE_NLS,;t t
s,@MKINSTALLDIRS@,$MKINSTALLDIRS,;t t
s,@MSGFMT@,$MSGFMT,;t t
diff --git a/elfutils/configure.ac b/elfutils/configure.ac
index 7315167b..f8d4ef35 100644
--- a/elfutils/configure.ac
+++ b/elfutils/configure.ac
@@ -16,18 +16,23 @@ dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software Foundation,
dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
dnl
-AC_INIT([Red Hat elfutils],[0.108],[http://bugzilla.redhat.com/bugzilla/],
+AC_INIT([Red Hat elfutils],[0.114],[http://bugzilla.redhat.com/bugzilla/],
[elfutils])
AC_CONFIG_AUX_DIR([config])
AC_CONFIG_FILES([config/Makefile])
AC_COPYRIGHT([Copyright (C) 1996-2003, 2004, 2005 Red Hat, Inc.])
-AC_REVISION($Revision: 1.45 $)
AC_PREREQ(2.59) dnl Minimum Autoconf version required.
AM_INIT_AUTOMAKE([gnits 1.7])
+dnl Unique ID for this build.
+MODVERSION="Build on $(hostname) $(date +%FT%R:%S%z)"
+AC_SUBST([MODVERSION])
+AC_DEFINE_UNQUOTED(MODVERSION, "$MODVERSION")
+AH_TEMPLATE([MODVERSION], [Identifier for modules in the build.])
+
AC_CONFIG_SRCDIR([libelf/libelf.h])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_HEADERS([config.h])
@@ -124,6 +129,26 @@ if test "$use_mudflap" = fail; then
fi
AM_CONDITIONAL(MUDFLAP, test "$use_mudflap" = yes)
+# Enable gprof suport.
+AC_ARG_ENABLE([gprof],
+AC_HELP_STRING([--enable-gprof],
+[build binaries with gprof support]), [use_gprof=yes], [use_gprof=no])
+if test "$use_gprof" = yes; then
+ CFLAGS="$CFLAGS -pg"
+ LDFLAGS="$LDFLAGS -pg"
+fi
+AM_CONDITIONAL(GPROF, test "$use_gprof" = yes)
+AM_CONDITIONAL(BUILD_STATIC, [dnl
+test "$use_mudflap" = yes -o "$use_gprof" = yes])
+
+LIBEBL_SUBDIR="$PACKAGE"
+AC_ARG_ENABLE([libebl-subdir],
+AS_HELP_STRING([--enable-libebl-subdir=DIR],
+[install libebl_CPU modules in $(libdir)/DIR]), [dnl
+LIBEBL_SUBDIR="$enable_libebl_subdir"])
+AC_SUBST([LIBEBL_SUBDIR])
+AC_DEFINE_UNQUOTED(LIBEBL_SUBDIR, "$LIBEBL_SUBDIR")
+AH_TEMPLATE([LIBEBL_SUBDIR], [$libdir subdirectory containing libebl modules.])
dnl The directories with content.
@@ -143,6 +168,9 @@ AC_CONFIG_FILES([libebl/Makefile])
dnl DWARF library.
AC_CONFIG_FILES([libdw/Makefile])
+dnl Higher-level DWARF support library.
+AC_CONFIG_FILES([libdwfl/Makefile])
+
dnl CPU handling library.
AC_CONFIG_FILES([libcpu/Makefile])
@@ -247,9 +275,13 @@ AH_BOTTOM([
# define INTDEF(name) _INTDEF(name)
# define _INTDEF(name) \
extern __typeof__ (name) __##name##_internal __attribute__ ((alias (#name)));
+# define INTDECL(name) _INTDECL(name)
+# define _INTDECL(name) \
+ extern __typeof__ (name) __##name##_internal attribute_hidden;
#else
# define INTUSE(name) name
# define INTDEF(name) /* empty */
+# define INTDECL(name) /* empty */
#endif
])
diff --git a/elfutils/elfutils.spec b/elfutils/elfutils.spec
index f5c1faaa..049477c2 100644
--- a/elfutils/elfutils.spec
+++ b/elfutils/elfutils.spec
@@ -2,7 +2,7 @@
%define fake 0
Summary: A collection of utilities and DSOs to handle compiled objects.
Name: elfutils
-Version: 0.108
+Version: 0.114
Release: 1
%if %{fake}
License: GPL
@@ -109,6 +109,8 @@ chmod +x ${RPM_BUILD_ROOT}%{_prefix}/%{_lib}/elfutils/lib*.so*
rm -f .%{_bindir}/eu-ld
rm -f .%{_includedir}/elfutils/libasm.h
rm -f .%{_libdir}/libasm-%{version}.so
+ rm -f .%{_libdir}/libasm.so.*
+ rm -f .%{_libdir}/libasm.so
rm -f .%{_libdir}/libasm.a
}
%endif
@@ -140,12 +142,13 @@ rm -rf ${RPM_BUILD_ROOT}
%{_bindir}/eu-strip
%{_bindir}/eu-findtextrel
%{_bindir}/eu-addr2line
+%{_bindir}/eu-elfcmp
%if !%{fake}
#%{_bindir}/eu-ld
#%{_libdir}/libasm-%{version}.so
%{_libdir}/libdw-%{version}.so
-#%{_libdir}/libasm*.so.*
-%{_libdir}/libdw*.so.*
+#%{_libdir}/libasm.so.*
+%{_libdir}/libdw.so.*
%dir %{_libdir}/elfutils
%{_libdir}/elfutils/lib*.so
%endif
@@ -158,6 +161,7 @@ rm -rf ${RPM_BUILD_ROOT}
%if !%{fake}
%{_includedir}/elfutils/libebl.h
%{_includedir}/elfutils/libdw.h
+%{_includedir}/elfutils/libdwfl.h
#%{_libdir}/libasm.a
%{_libdir}/libebl.a
%{_libdir}/libdw.a
@@ -168,7 +172,7 @@ rm -rf ${RPM_BUILD_ROOT}
%files libelf
%defattr(-,root,root)
%{_libdir}/libelf-%{version}.so
-%{_libdir}/libelf*.so.*
+%{_libdir}/libelf.so.*
%files libelf-devel
%defattr(-,root,root)
@@ -179,6 +183,65 @@ rm -rf ${RPM_BUILD_ROOT}
%{_libdir}/libelf.so
%changelog
+* Wed Aug 24 2005 Ulrich Drepper <drepper@redhat.com> 0.114-1
+- libelf: new function elf_getaroff
+- libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_inst
+ances.
+- libdwfl: New functions dwfl_report_offline, dwfl_offline_section_addre
+ss, dwfl_linux_kernel_report_offline.
+- ranlib: new program
+
+* Mon Aug 15 2005 Ulrich Drepper <drepper@redhat.com> 0.114-1
+- libelf: new function elf_getaroff
+- ranlib: new program
+
+* Wed Aug 10 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections. Allow .rodata
+sectionto have STRINGS and MERGE flag set.
+- strip: add some more compatibility with binutils.
+
+* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections. Allow .rodata
+sectionto have STRINGS and MERGE flag set.
+
+* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections.
+
+* Fri Aug 5 2005 Ulrich Drepper <@redhat.com> 0.112-1
+- elfcmp: some more relaxation.
+- elflint: many more tests, especially regarding to symbol versioning.
+- libelf: Add elfXX_offscn and gelf_offscn.
+- libasm: asm_begin interface changes.
+- libebl: Add three new interfaces to directly access machine, class, an
+ddata encoding information.
+- objdump: New program. Just the beginning.
+
+* Thu Jul 28 2005 Ulrich Drepper <@redhat.com> 0.111-1
+- libdw: now contains all of libdwfl. The latter is not installed anymore.
+- elfcmp: little usability tweak, name and index of differing section is
+ printed.
+
+* Sun Jul 24 2005 Ulrich Drepper <@redhat.com> 0.110-1
+- libelf: fix a numbe rof problems with elf_update
+- elfcmp: fix a few bugs. Compare gaps.
+- Fix a few PLT problems and mudflap build issues.
+- libebl: Don't expose Ebl structure definition in libebl.h. It's now p
+rivate.
+
+* Thu Jul 21 2005 Ulrich Drepper <@redhat.com> 0.109-1
+- libebl: Check for matching modules.
+- elflint: Check that copy relocations only happen for OBJECT or NOTYPE
+symbols.
+- elfcmp: New program.
+- libdwfl: New library.
+
+* Mon May 9 2005 Ulrich Drepper <@redhat.com> 0.108-1
+- strip: fix bug introduced in last change
+- libdw: records returned by dwarf_getsrclines are now sorted by address
+
* Sun May 8 2005 Ulrich Drepper <@redhat.com> 0.108-1
- strip: fix bug introduced in last change
diff --git a/elfutils/lib/ChangeLog b/elfutils/lib/ChangeLog
index 9ddc2163..5b79d096 100644
--- a/elfutils/lib/ChangeLog
+++ b/elfutils/lib/ChangeLog
@@ -1,3 +1,7 @@
+2005-08-06 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (xmalloc_CFLAGS): Define only if !GPROF.
+
2005-05-03 Roland McGrath <roland@redhat.com>
* crc32_file.c: New file.
diff --git a/elfutils/lib/Makefile.am b/elfutils/lib/Makefile.am
index facb5634..b34d5440 100644
--- a/elfutils/lib/Makefile.am
+++ b/elfutils/lib/Makefile.am
@@ -32,4 +32,6 @@ libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \
noinst_HEADERS = fixedsizehash.h system.h dynamicsizehash.h list.h
EXTRA_DIST = dynamicsizehash.c
+if !GPROF
xmalloc_CFLAGS = -ffunction-sections
+endif
diff --git a/elfutils/lib/Makefile.in b/elfutils/lib/Makefile.in
index 4d0ff2de..25d95b55 100644
--- a/elfutils/lib/Makefile.in
+++ b/elfutils/lib/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -15,8 +15,6 @@
@SET_MAKE@
-SOURCES = $(libeu_a_SOURCES)
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -80,6 +78,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -93,6 +93,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -101,12 +103,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -179,7 +183,7 @@ libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \
noinst_HEADERS = fixedsizehash.h system.h dynamicsizehash.h list.h
EXTRA_DIST = dynamicsizehash.c
-xmalloc_CFLAGS = -ffunction-sections
+@GPROF_FALSE@xmalloc_CFLAGS = -ffunction-sections
all: all-am
.SUFFIXES:
diff --git a/elfutils/libasm/ChangeLog b/elfutils/libasm/ChangeLog
index 8b7b44d2..6adeef1e 100644
--- a/elfutils/libasm/ChangeLog
+++ b/elfutils/libasm/ChangeLog
@@ -1,6 +1,22 @@
+2005-08-02 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (AM_CFLAGS): Add -std=gnu99.
+ * asm_abort.c: Don't try to remove output file if there is none.
+ * asm_addint8.c: In print mode, print to file not stdout.
+ * asm_addsleb128.c: Likewise.
+ * asm_adduleb128.c: Likewise.
+ * asm_newscn.c: Likewise.
+ * asm_align.c: Implement print mode.
+ * asm_begin.c (asm_begin): Change interface. Take binary class and
+ byte order information from new Ebl parameter.
+ * libasm.h: Adjust prototype.
+ * asm_end.c (text_end): Close file if necesary.
+ * asm_error.c: Add new error ASM_E_IOERROR.
+ * libasmP.h: Add ASM_E_IOERROR definition.
+
2005-02-15 Ulrich Drepper <drepper@redhat.com>
- * Makefile (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
+ * Makefile.am (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
* asm_end.c (text_end): Mark parameter as possibly unused.
diff --git a/elfutils/libasm/Makefile.am b/elfutils/libasm/Makefile.am
index 34b19d24..7802a5c0 100644
--- a/elfutils/libasm/Makefile.am
+++ b/elfutils/libasm/Makefile.am
@@ -18,7 +18,7 @@ AM_CFLAGS = -fmudflap
else
AM_CFLAGS =
endif
-AM_CFLAGS += -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2
+AM_CFLAGS += -std=gnu99 -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2
INCLUDES = -I. -I$(srcdir) -I.. -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl \
-I$(top_srcdir)/lib
GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
diff --git a/elfutils/libasm/Makefile.in b/elfutils/libasm/Makefile.in
index 7d2121c9..875106cf 100644
--- a/elfutils/libasm/Makefile.in
+++ b/elfutils/libasm/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,8 +16,6 @@
-SOURCES = $(libasm_a_SOURCES) $(libasm_pic_a_SOURCES) $(libasm_so_SOURCES)
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -112,6 +110,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -125,6 +125,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -133,12 +135,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -200,10 +204,10 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Wshadow -Werror -Wunused -Wextra \
-@MUDFLAP_FALSE@ -Wformat=2
-@MUDFLAP_TRUE@AM_CFLAGS = -fmudflap -Wall -Wshadow -Werror -Wunused \
-@MUDFLAP_TRUE@ -Wextra -Wformat=2
+@MUDFLAP_FALSE@AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Werror -Wunused \
+@MUDFLAP_FALSE@ -Wextra -Wformat=2
+@MUDFLAP_TRUE@AM_CFLAGS = -fmudflap -std=gnu99 -Wall -Wshadow -Werror \
+@MUDFLAP_TRUE@ -Wunused -Wextra -Wformat=2
INCLUDES = -I. -I$(srcdir) -I.. -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl \
-I$(top_srcdir)/lib
diff --git a/elfutils/libasm/asm_abort.c b/elfutils/libasm/asm_abort.c
index f35757ca..3353a023 100644
--- a/elfutils/libasm/asm_abort.c
+++ b/elfutils/libasm/asm_abort.c
@@ -1,5 +1,5 @@
/* Abort operations on the assembler context, free all resources.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -36,7 +36,8 @@ asm_abort (ctx)
(void) elf_end (ctx->out.elf);
/* Now close the temporary file and remove it. */
- (void) unlink (ctx->tmp_fname);
+ if (ctx->fd != -1)
+ (void) unlink (ctx->tmp_fname);
/* Free the resources. */
__libasm_finictx (ctx);
diff --git a/elfutils/libasm/asm_addint8.c b/elfutils/libasm/asm_addint8.c
index 35d9bf57..bbd8e5f7 100644
--- a/elfutils/libasm/asm_addint8.c
+++ b/elfutils/libasm/asm_addint8.c
@@ -1,5 +1,5 @@
/* Add integer to a section.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -53,22 +53,25 @@ FCT(SIZE) (asmscn, num)
{
// XXX Needs to use backend specified pseudo-ops
if (SIZE == 8)
- printf ("\t.byte\t%" PRId8 "\n", (int8_t) num);
+ fprintf (asmscn->ctx->out.file, "\t.byte\t%" PRId8 "\n", (int8_t) num);
else if (SIZE == 16)
- printf ("\t.value\t%" PRId16 "\n", (int16_t) num);
+ fprintf (asmscn->ctx->out.file, "\t.value\t%" PRId16 "\n",
+ (int16_t) num);
else if (SIZE == 32)
- printf ("\t.long\t%" PRId32 "\n", (int32_t) num);
+ fprintf (asmscn->ctx->out.file, "\t.long\t%" PRId32 "\n",
+ (int32_t) num);
else
{
// XXX This is not necessary for 64-bit machines
bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA]
== ELFDATA2LSB);
- printf ("\t.long\t%" PRId32 "\n\t.long\t%" PRId32 "\n",
- (int32_t) (is_leb
- ? num % 0x100000000ll : num / 0x100000000ll),
- (int32_t) (is_leb
- ? num / 0x100000000ll : num % 0x100000000ll));
+ fprintf (asmscn->ctx->out.file,
+ "\t.long\t%" PRId32 "\n\t.long\t%" PRId32 "\n",
+ (int32_t) (is_leb
+ ? num % 0x100000000ll : num / 0x100000000ll),
+ (int32_t) (is_leb
+ ? num / 0x100000000ll : num % 0x100000000ll));
}
}
else
diff --git a/elfutils/libasm/asm_addsleb128.c b/elfutils/libasm/asm_addsleb128.c
index 0661b36e..fdefd01b 100644
--- a/elfutils/libasm/asm_addsleb128.c
+++ b/elfutils/libasm/asm_addsleb128.c
@@ -1,5 +1,5 @@
/* Add signed little endian base 128 integer to a section.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -37,7 +37,7 @@ asm_addsleb128 (asmscn, num)
}
if (unlikely (asmscn->ctx->textp))
- printf ("\t.sleb128\t%" PRId32 "\n", num);
+ fprintf (asmscn->ctx->out.file, "\t.sleb128\t%" PRId32 "\n", num);
else
{
char tmpbuf[(sizeof (num) * 8 + 6) / 7];
diff --git a/elfutils/libasm/asm_adduleb128.c b/elfutils/libasm/asm_adduleb128.c
index 521d265a..1685b5eb 100644
--- a/elfutils/libasm/asm_adduleb128.c
+++ b/elfutils/libasm/asm_adduleb128.c
@@ -1,5 +1,5 @@
/* Add integer to a section.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -37,7 +37,7 @@ asm_adduleb128 (asmscn, num)
}
if (unlikely (asmscn->ctx->textp))
- printf ("\t.uleb128\t%" PRIu32 "\n", num);
+ fprintf (asmscn->ctx->out.file, "\t.uleb128\t%" PRIu32 "\n", num);
else
{
char tmpbuf[(sizeof (num) * 8 + 6) / 7];
diff --git a/elfutils/libasm/asm_align.c b/elfutils/libasm/asm_align.c
index e7350924..a52fc86d 100644
--- a/elfutils/libasm/asm_align.c
+++ b/elfutils/libasm/asm_align.c
@@ -1,5 +1,5 @@
/* Align section.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -16,6 +16,7 @@
# include <config.h>
#endif
+#include <inttypes.h>
#include <stdlib.h>
#include <sys/param.h>
@@ -39,6 +40,25 @@ asm_align (asmscn, value)
return -1;
}
+ if (unlikely (asmscn->ctx->textp))
+ {
+ fprintf (asmscn->ctx->out.file, "\t.align %" PRId32 ", ",
+ (int32_t) value);
+ if (asmscn->pattern->len == 1)
+ fprintf (asmscn->ctx->out.file, "%02hhx\n", asmscn->pattern->bytes[0]);
+ else
+ {
+ fputc_unlocked ('"', asmscn->ctx->out.file);
+
+ for (size_t cnt = 0; cnt < asmscn->pattern->len; ++cnt)
+ fprintf (asmscn->ctx->out.file, "\\x%02hhx",
+ asmscn->pattern->bytes[cnt]);
+
+ fputs_unlocked ("\"\n", asmscn->ctx->out.file);
+ }
+ return 0;
+ }
+
rwlock_wrlock (asmscn->ctx->lock);
int result = 0;
@@ -47,10 +67,7 @@ asm_align (asmscn, value)
if ((asmscn->offset & (value - 1)) != 0)
{
/* Add fillbytes. */
- size_t cnt;
- size_t byteptr;
-
- cnt = value - (asmscn->offset & (value - 1));
+ size_t cnt = value - (asmscn->offset & (value - 1));
/* Ensure there is enough room to add the fill bytes. */
result = __libasm_ensure_section_space (asmscn, cnt);
@@ -59,7 +76,7 @@ asm_align (asmscn, value)
/* Fill in the bytes. We align the pattern according to the
current offset. */
- byteptr = asmscn->offset % asmscn->pattern->len;
+ size_t byteptr = asmscn->offset % asmscn->pattern->len;
/* Update the total size. */
asmscn->offset += cnt;
diff --git a/elfutils/libasm/asm_begin.c b/elfutils/libasm/asm_begin.c
index 3896f78f..1ded3474 100644
--- a/elfutils/libasm/asm_begin.c
+++ b/elfutils/libasm/asm_begin.c
@@ -18,6 +18,8 @@
#include <assert.h>
#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -30,12 +32,27 @@
static AsmCtx_t *
prepare_text_output (AsmCtx_t *result)
{
+ if (result->fd == -1)
+ result->out.file = stdout;
+ else
+ {
+ result->out.file = fdopen (result->fd, "a");
+ if (result->out.file == NULL)
+ {
+ close (result->fd);
+ free (result);
+ result = NULL;
+ }
+
+ __fsetlocking (result->out.file, FSETLOCKING_BYCALLER);
+ }
+
return result;
}
static AsmCtx_t *
-prepare_binary_output (AsmCtx_t *result, int machine, int klass, int data)
+prepare_binary_output (AsmCtx_t *result, Ebl *ebl)
{
GElf_Ehdr *ehdr;
GElf_Ehdr ehdr_mem;
@@ -53,7 +70,8 @@ prepare_binary_output (AsmCtx_t *result, int machine, int klass, int data)
}
/* Create the ELF header for the output file. */
- if (gelf_newehdr (result->out.elf, klass) == 0)
+ int class = ebl_get_elfclass (ebl);
+ if (gelf_newehdr (result->out.elf, class) == 0)
goto err_libelf;
ehdr = gelf_getehdr (result->out.elf, &ehdr_mem);
@@ -65,11 +83,10 @@ prepare_binary_output (AsmCtx_t *result, int machine, int klass, int data)
/* Set the ELF version. */
ehdr->e_version = EV_CURRENT;
- /* Use the machine value the user provided. */
- ehdr->e_machine = machine;
- /* Same for the class and endianness. */
- ehdr->e_ident[EI_CLASS] = klass;
- ehdr->e_ident[EI_DATA] = data;
+ /* Use the machine, class, and endianess values from the Ebl descriptor. */
+ ehdr->e_machine = ebl_get_elfmachine (ebl);
+ ehdr->e_ident[EI_CLASS] = class;
+ ehdr->e_ident[EI_DATA] = ebl_get_elfdata (ebl);
memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
@@ -95,47 +112,48 @@ prepare_binary_output (AsmCtx_t *result, int machine, int klass, int data)
AsmCtx_t *
-asm_begin (fname, textp, machine, klass, data)
+asm_begin (fname, ebl, textp)
const char *fname;
+ Ebl *ebl;
bool textp;
- int machine;
- int klass;
- int data;
{
- size_t fname_len = strlen (fname);
- AsmCtx_t *result;
-
+ if (fname == NULL && ! textp)
+ return NULL;
- /* First order of business: find the appropriate backend. If it
- does not exist we don't have to look further. */
- // XXX
+ size_t fname_len = fname != NULL ? strlen (fname) : 0;
/* Create the file descriptor. We do not generate the output file
right away. Instead we create a temporary file in the same
directory which, if everything goes alright, will replace a
possibly existing file with the given name. */
- result = (AsmCtx_t *) malloc (sizeof (AsmCtx_t) + 2 * fname_len + 9);
+ AsmCtx_t *result
+ = (AsmCtx_t *) malloc (sizeof (AsmCtx_t) + 2 * fname_len + 9);
if (result == NULL)
return NULL;
- /* Initialize the lock. */
- rwlock_init (result->lock);
-
- /* Create the name of the temporary file. */
- result->fname = stpcpy (mempcpy (result->tmp_fname, fname, fname_len),
- ".XXXXXX") + 1;
- memcpy (result->fname, fname, fname_len + 1);
+ /* Initialize the lock. */
+ rwlock_init (result->lock);
- /* Create the temporary file. */
- result->fd = mkstemp (result->tmp_fname);
- if (result->fd == -1)
+ if (fname != NULL)
{
- int save_errno = errno;
- free (result);
- __libasm_seterrno (ASM_E_CANNOT_CREATE);
- errno = save_errno;
- return NULL;
+ /* Create the name of the temporary file. */
+ result->fname = stpcpy (mempcpy (result->tmp_fname, fname, fname_len),
+ ".XXXXXX") + 1;
+ memcpy (result->fname, fname, fname_len + 1);
+
+ /* Create the temporary file. */
+ result->fd = mkstemp (result->tmp_fname);
+ if (result->fd == -1)
+ {
+ int save_errno = errno;
+ free (result);
+ __libasm_seterrno (ASM_E_CANNOT_CREATE);
+ errno = save_errno;
+ return NULL;
+ }
}
+ else
+ result->fd = -1;
/* Initialize the counter for temporary symbols. */
result->tempsym_count = 0;
@@ -145,7 +163,7 @@ asm_begin (fname, textp, machine, klass, data)
if (textp)
result = prepare_text_output (result);
else
- result = prepare_binary_output (result, machine, klass, data);
+ result = prepare_binary_output (result, ebl);
return result;
}
diff --git a/elfutils/libasm/asm_end.c b/elfutils/libasm/asm_end.c
index 74f01f08..33191f9c 100644
--- a/elfutils/libasm/asm_end.c
+++ b/elfutils/libasm/asm_end.c
@@ -33,7 +33,12 @@
static int
text_end (AsmCtx_t *ctx __attribute__ ((unused)))
{
- // XXX Does anything have to be done?
+ if (fclose (ctx->out.file) != 0)
+ {
+ __libasm_seterrno (ASM_E_IOERROR);
+ return -1;
+ }
+
return 0;
}
diff --git a/elfutils/libasm/asm_error.c b/elfutils/libasm/asm_error.c
index 9d2d81ed..3b5aa055 100644
--- a/elfutils/libasm/asm_error.c
+++ b/elfutils/libasm/asm_error.c
@@ -1,5 +1,5 @@
/* Error handling in libasm.
- Copyright (C) 2002, 2004 Red Hat, Inc.
+ Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -112,7 +112,8 @@ static const char *msgs[ASM_E_NUM] =
[ASM_E_CANNOT_CHMOD] = N_("cannot change mode of output file"),
[ASM_E_CANNOT_RENAME] = N_("cannot rename output file"),
[ASM_E_DUPLSYM] = N_("duplicate symbol"),
- [ASM_E_TYPE] = N_("invalid section type for operation")
+ [ASM_E_TYPE] = N_("invalid section type for operation"),
+ [ASM_E_IOERROR] = N_("error during output of data"),
};
const char *
diff --git a/elfutils/libasm/asm_newscn.c b/elfutils/libasm/asm_newscn.c
index 75890a60..7e585325 100644
--- a/elfutils/libasm/asm_newscn.c
+++ b/elfutils/libasm/asm_newscn.c
@@ -1,5 +1,5 @@
/* Create new section in output file.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -81,7 +81,8 @@ text_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags)
/* Terminate the string. */
*wp = '\0';
- printf ("\t.section \"%s\"%s%s\n", result->name, flagstr, typestr);
+ fprintf (result->ctx->out.file, "\t.section \"%s\"%s%s\n",
+ result->name, flagstr, typestr);
return result;
}
diff --git a/elfutils/libasm/libasm.h b/elfutils/libasm/libasm.h
index dbdd6fc2..46d5e8db 100644
--- a/elfutils/libasm/libasm.h
+++ b/elfutils/libasm/libasm.h
@@ -1,5 +1,5 @@
/* Interface for libasm.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -17,7 +17,7 @@
#include <stdbool.h>
#include <stdint.h>
-#include <gelf.h>
+#include <libebl.h>
/* Opaque type for the assembler context descriptor. */
@@ -43,8 +43,7 @@ extern "C" {
corresponds to an EM_ constant from <elf.h>, KLASS specifies the
class (32- or 64-bit), and DATA specifies the byte order (little or
big endian). */
-extern AsmCtx_t *asm_begin (const char *fname, bool textp, int machine,
- int klass, int data);
+extern AsmCtx_t *asm_begin (const char *fname, Ebl *ebl, bool textp);
/* Abort the operation on the assembler context and free all resources. */
extern int asm_abort (AsmCtx_t *ctx);
diff --git a/elfutils/libasm/libasmP.h b/elfutils/libasm/libasmP.h
index 2e4954f6..1cbec55c 100644
--- a/elfutils/libasm/libasmP.h
+++ b/elfutils/libasm/libasmP.h
@@ -1,5 +1,5 @@
/* Internal definitions for libasm.
- Copyright (C) 2002, 2004 Red Hat, Inc.
+ Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -17,7 +17,6 @@
#include <stdio.h>
#include <libasm.h>
-#include <libebl.h>
/* gettext helper macros. */
#define _(Str) dgettext ("elfutils", Str)
@@ -35,6 +34,7 @@ enum
ASM_E_DUPLSYM, /* Duplicate symbol definition. */
ASM_E_LIBELF, /* Refer to error in libelf. */
ASM_E_TYPE, /* Invalid section type for operation. */
+ ASM_E_IOERROR, /* Error during output of data. */
ASM_E_NUM /* Keep this entry as the last. */
};
diff --git a/elfutils/libcpu/Makefile.in b/elfutils/libcpu/Makefile.in
index fec0acab..fc3a6a9a 100644
--- a/elfutils/libcpu/Makefile.in
+++ b/elfutils/libcpu/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -14,8 +14,6 @@
@SET_MAKE@
-SOURCES = $(libcpu_i386_a_SOURCES)
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -75,6 +73,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -88,6 +88,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -96,12 +98,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
diff --git a/elfutils/libdw/ChangeLog b/elfutils/libdw/ChangeLog
index f6105c8c..3b84ab9e 100644
--- a/elfutils/libdw/ChangeLog
+++ b/elfutils/libdw/ChangeLog
@@ -1,3 +1,198 @@
+2005-08-23 Roland McGrath <roland@redhat.com>
+
+ * dwarf_attr_integrate.c (dwarf_attr_integrate): Treat
+ DW_AT_specification the same as DW_AT_abstract_origin.
+
+2005-08-20 Roland McGrath <roland@redhat.com>
+
+ * libdw.map: Add dwfl_cumodule, remove dwfl_linecu.
+ Add dwfl_linux_kernel_report_offline, dwfl_offline_section_address,
+ and dwfl_report_offline.
+
+2005-08-19 Roland McGrath <roland@redhat.com>
+
+ * libdw.map: Bump version to ELFUTILS_0.114 for libdwfl changes.
+ Add dwfl_module_relocate_address, dwfl_module_relocations,
+ dwfl_module_relocation_info.
+
+2005-08-18 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getscopes.c (dwarf_getscopes): Include the CU itself as
+ outermost scope in the results.
+
+2005-08-15 Roland McGrath <roland@redhat.com>
+
+ * dwarf_func_inline.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add it.
+ * libdw.h: Declare dwarf_func_inline, dwarf_func_inline_instances.
+ * libdw.map: Add them.
+
+ * dwarf_func_die.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add it.
+ * libdw.h: Declare dwarf_func_die.
+ * libdw.map: Add it. Bump version to ELFUTILS_0.114.
+
+2005-08-10 Ulrich Drepper <drepper@redhat.com>
+
+ * dwarf_getsrclines.c (dwarf_getsrclines): Correct fallout of renaming
+ of DW_LNS_set_epilog_begin.
+
+2005-08-09 Roland McGrath <roland@redhat.com>
+
+ * dwarf.h (DW_LNS_set_epilog_begin): Renamed DW_LNS_set_epilogue_begin.
+
+ * dwarf_end.c: Add INTDEF.
+ * dwarf_error.c (dwarf_errmsg): Likewise.
+ * libdwP.h (dwarf_end, dwarf_errmsg): Add INTDECLs.
+
+2005-08-01 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getaranges.c (dwarf_getaranges): Check for bogus offset.
+ * dwarf_getabbrev.c (__libdw_getabbrev): Likewise.
+
+2005-07-28 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (libdw.so): No need to link with libeu.a anymore.
+ (libdw_a_LIBADD): Add all files from libdwfl.a.
+
+2005-07-27 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am (libdw.so): Link ../libdwfl/libdwfl_pic.a in,
+ along with ../libebl/libebl.a and ../lib/libeu.a;
+ depend on ../libelf/libelf.so.
+ (libdw_so_LDADD): New variable.
+ * libdw.map: Add dwfl_* symbols formerly in ../libdwfl/libdwfl.map.
+
+ * libdw.map: Define an empty base version and move all symbols to
+ version ELFUTILS_0.111; don't define ELFUTILS_1.0 at all yet.
+
+2005-07-23 Ulrich Drepper <drepper@redhat.com>
+
+ * dwarf_error.c: Add internal alias for dwarf_errno.
+ * libdwP.h: Declare __dwarf_errno_internal.
+ * dwarf_getloclist.c: Use INTDEF for dwarf_errno.
+
+ * dwarf_error.c [USE_TLS]: Actually use __thread in definition of
+ global_error.
+
+2005-06-01 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getaranges.c (dwarf_getaranges): Sort result array.
+ * dwarf_getarange_addr.c (dwarf_getarange_addr): Use binary search.
+
+2005-06-08 Roland McGrath <roland@redhat.com>
+
+ * memory-access.h (get_uleb128_step, get_uleb128): Remove casts.
+ (get_sleb128_step, get_sleb128): Likewise.
+ * dwarf_getattrs.c (dwarf_getattrs): Add consts.
+ * dwarf_getloclist.c (getloclist): Likewise.
+ * dwarf_formblock.c (dwarf_formblock): Likewise.
+ * dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+ * dwarf_getabbrevattr.c (dwarf_getabbrevattr): Likewise.
+ * dwarf_formref.c (dwarf_formref): Likewise.
+ * dwarf_formsdata.c (dwarf_formsdata): Likewise.
+ * dwarf_formudata.c (dwarf_formudata): Likewise.
+ * dwarf_haschildren.c (dwarf_haschildren): Likewise.
+ * dwarf_child.c (__libdw_find_attr, __libdw_find_attr): Likewise.
+ * dwarf_tag.c (dwarf_tag): Likewise.
+ * dwarf_getabbrev.c (__libdw_getabbrev): Likewise.
+ * memory-access.c (__libdw_get_uleb128, __libdw_get_sleb128): Likewise.
+ * libdw_form.c (__libdw_form_val_len): Likewise.
+ * libdwP.h: Update decl.
+
+2005-06-04 Roland McGrath <roland@redhat.com>
+
+ * memory-access.h (get_uleb128_rest_return): New macro.
+ [! IS_LIBDW] (__libdw_get_uleb128): New static, defined using it.
+ (get_sleb128_rest_return): New macro.
+ [! IS_LIBDW] (__libdw_get_sleb128): New static, defined using it.
+ * memory-access.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add it.
+ (DEFS): Add -DIS_LIBDW.
+
+2005-05-31 Roland McGrath <roland@redhat.com>
+
+ * dwarf_formref_die.c (dwarf_formref_die): Add CU header offset to
+ formref offset.
+
+2005-05-30 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getloclist.c (dwarf_addrloclists): Use DW_AT_entry_pc for base
+ address if DW_AT_low_pc is missing. Not to spec, but GCC generates it.
+
+ * dwarf_getloclist.c (dwarf_addrloclists): Don't sign-extend 4-byte
+ BEGIN value. Instead, match base address entries separately for
+ 32/64 size cases.
+
+2005-05-28 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getloclist.c (dwarf_addrloclists): Fix decoding to advance
+ past location expression contents.
+
+2005-05-23 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getsrclines.c: Comment typo fix.
+
+ * dwarf_haspc.c (dwarf_haspc): Fix CU DIE address calculation.
+ * dwarf_getloclist.c (dwarf_addrloclists): Likewise.
+
+2005-05-22 Ulrich Drepper <drepper@redhat.com>
+
+ * libdwP.h: Only use INTDECL for alias prototypes.
+
+2005-05-19 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getloclist.c (attr_ok): Permit DW_AT_static_link too.
+
+ * dwarf_getscopevar.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add it.
+ * libdw.h: Declare dwarf_getscopevar.
+
+ * dwarf_getsrcfiles.c: Add INTDEF.
+ * dwarf_haschildren.c: Likewise.
+ * libdwP.h (dwarf_getsrcfiles, dwarf_haschildren): Add INTDECL.
+
+ * dwarf_getscopes.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add it.
+ * libdw.h: Declare dwarf_getscopes.
+ * libdw.map: Add it.
+
+2005-05-18 Roland McGrath <roland@redhat.com>
+
+ * libdwP.h (IDX_debug_ranges): New enum constant.
+ * dwarf_begin_elf.c (dwarf_scnnames): Add it for ".debug_ranges".
+ * libdwP.h (DWARF_E_NO_DEBUG_RANGES): New enum constant.
+ * dwarf_error.c (errmsgs): Add it.
+ * dwarf_haspc.c: New file.
+ * libdw.h: Declare dwarf_haspc.
+ * libdw.map: Add it.
+ * libdwP.h: Add INTDECL.
+
+ * dwarf_attr_integrate.c: New file.
+ * dwarf_hasattr_integrate.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add them.
+ * libdw.h: Declare dwarf_attr_integrate, dwarf_hasattr_integrate.
+ * libdw.map: Add them.
+
+ * dwarf_hasattr.c: Add INTDEF.
+ * libdwP.h: Add INTDECL for it.
+
+ * dwarf_formref_die.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add it.
+ * libdw.h (dwarf_formref_die): Declare it.
+ * libdwP.h (dwarf_formref_die): Add INTDECL.
+ * libdw.map: Add it.
+
+ * dwarf_getloclist.c (attr_ok, getloclist): New functions, broken out
+ of ...
+ (dwarf_getloclist): ... here. Call them.
+ (dwarf_addrloclists): New function.
+ * libdw.h: Declare it.
+ * libdw.map: Add it.
+
+ * dwarf_getmacros.c (dwarf_getmacros): Don't bail at
+ DW_MACINFO_end_file. Recognize type 0 as terminator.
+
2005-05-05 Roland McGrath <roland@redhat.com>
* dwarf_getsrc_die.c (dwarf_getsrc_die): Use binary search.
diff --git a/elfutils/libdw/Makefile.am b/elfutils/libdw/Makefile.am
index cdecf32d..ad6b28a1 100644
--- a/elfutils/libdw/Makefile.am
+++ b/elfutils/libdw/Makefile.am
@@ -12,7 +12,7 @@
## by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
## 3001 King Ranch Road, Ukiah, CA 95482.
##
-DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DIS_LIBDW
if MUDFLAP
AM_CFLAGS = -fmudflap
else
@@ -36,9 +36,11 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \
dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \
dwarf_attr.c dwarf_formstring.c dwarf_abbrev_hash.c \
+ dwarf_attr_integrate.c dwarf_hasattr_integrate.c \
dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \
dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \
- dwarf_highpc.c dwarf_formref.c dwarf_siblingof.c \
+ dwarf_haspc.c dwarf_highpc.c \
+ dwarf_formref.c dwarf_formref_die.c dwarf_siblingof.c \
dwarf_dieoffset.c dwarf_cuoffset.c dwarf_hasattr.c \
dwarf_hasform.c dwarf_whatform.c dwarf_whatattr.c \
dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \
@@ -46,6 +48,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \
dwarf_getattrcnt.c dwarf_getabbrevattr.c \
dwarf_getsrclines.c dwarf_getsrc_die.c \
+ dwarf_getscopes.c dwarf_getscopevar.c \
dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \
dwarf_linecol.c dwarf_linebeginstatement.c \
dwarf_lineendsequence.c dwarf_lineblock.c \
@@ -59,8 +62,10 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
dwarf_macro_param2.c dwarf_addrdie.c \
dwarf_getfuncs.c dwarf_func_name.c dwarf_func_lowpc.c \
dwarf_func_highpc.c dwarf_func_entrypc.c dwarf_func_file.c \
- dwarf_func_line.c dwarf_func_col.c dwarf_getsrc_file.c \
- libdw_findcu.c libdw_form.c libdw_alloc.c
+ dwarf_func_line.c dwarf_func_col.c dwarf_func_die.c \
+ dwarf_func_inline.c dwarf_getsrc_file.c \
+ libdw_findcu.c libdw_form.c libdw_alloc.c memory-access.c \
+ libdw_visit_scopes.c
if !MUDFLAP
@@ -68,15 +73,16 @@ libdw_pic_a_SOURCES =
am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
libdw_so_SOURCES =
-libdw.so: libdw_pic.a $(srcdir)/libdw.map
- $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
- -Wl,--version-script,$(srcdir)/libdw.map,--no-undefined \
- -Wl,--soname,$@.$(VERSION),-z,defs \
- ../libelf/libelf.so
+libdw.so: $(srcdir)/libdw.map libdw_pic.a \
+ ../libdwfl/libdwfl_pic.a ../libebl/libebl.a \
+ ../libelf/libelf.so
+ $(CC) -shared -o $@ -Wl,--soname,$@.$(VERSION),-z,defs \
+ -Wl,--version-script,$<,--no-undefined \
+ -Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive \
+ -ldl
if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
ln -fs $@ $@.$(VERSION)
-
%.os: %.c %.o
if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
-MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
@@ -98,6 +104,8 @@ uninstall: uninstall-am
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
endif
+libdw_a_LIBADD = $(addprefix ../libdwfl/,$(shell $(AR) t ../libdwfl/libdwfl.a))
+
noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h
EXTRA_DIST = libdw.map
diff --git a/elfutils/libdw/Makefile.in b/elfutils/libdw/Makefile.in
index 44ac5252..47a7217f 100644
--- a/elfutils/libdw/Makefile.in
+++ b/elfutils/libdw/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,8 +16,6 @@
-SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) $(libdw_so_SOURCES)
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -67,7 +65,9 @@ LIBRARIES = $(lib_LIBRARIES) $(noinst_LIBRARIES)
AR = ar
ARFLAGS = cru
libdw_a_AR = $(AR) $(ARFLAGS)
-libdw_a_LIBADD =
+am__DEPENDENCIES_1 = ar
+libdw_a_DEPENDENCIES = $(addprefix ../libdwfl/,$(shell \
+ $(am__DEPENDENCIES_1) t ../libdwfl/libdwfl.a))
am_libdw_a_OBJECTS = dwarf_begin.$(OBJEXT) dwarf_begin_elf.$(OBJEXT) \
dwarf_end.$(OBJEXT) dwarf_getelf.$(OBJEXT) \
dwarf_getpubnames.$(OBJEXT) dwarf_getabbrev.$(OBJEXT) \
@@ -75,20 +75,24 @@ am_libdw_a_OBJECTS = dwarf_begin.$(OBJEXT) dwarf_begin_elf.$(OBJEXT) \
dwarf_nextcu.$(OBJEXT) dwarf_diename.$(OBJEXT) \
dwarf_offdie.$(OBJEXT) dwarf_attr.$(OBJEXT) \
dwarf_formstring.$(OBJEXT) dwarf_abbrev_hash.$(OBJEXT) \
- dwarf_child.$(OBJEXT) dwarf_haschildren.$(OBJEXT) \
- dwarf_formaddr.$(OBJEXT) dwarf_formudata.$(OBJEXT) \
- dwarf_formsdata.$(OBJEXT) dwarf_lowpc.$(OBJEXT) \
+ dwarf_attr_integrate.$(OBJEXT) \
+ dwarf_hasattr_integrate.$(OBJEXT) dwarf_child.$(OBJEXT) \
+ dwarf_haschildren.$(OBJEXT) dwarf_formaddr.$(OBJEXT) \
+ dwarf_formudata.$(OBJEXT) dwarf_formsdata.$(OBJEXT) \
+ dwarf_lowpc.$(OBJEXT) dwarf_haspc.$(OBJEXT) \
dwarf_highpc.$(OBJEXT) dwarf_formref.$(OBJEXT) \
- dwarf_siblingof.$(OBJEXT) dwarf_dieoffset.$(OBJEXT) \
- dwarf_cuoffset.$(OBJEXT) dwarf_hasattr.$(OBJEXT) \
- dwarf_hasform.$(OBJEXT) dwarf_whatform.$(OBJEXT) \
- dwarf_whatattr.$(OBJEXT) dwarf_bytesize.$(OBJEXT) \
- dwarf_arrayorder.$(OBJEXT) dwarf_bitsize.$(OBJEXT) \
- dwarf_bitoffset.$(OBJEXT) dwarf_srclang.$(OBJEXT) \
- dwarf_getabbrevtag.$(OBJEXT) dwarf_getabbrevcode.$(OBJEXT) \
+ dwarf_formref_die.$(OBJEXT) dwarf_siblingof.$(OBJEXT) \
+ dwarf_dieoffset.$(OBJEXT) dwarf_cuoffset.$(OBJEXT) \
+ dwarf_hasattr.$(OBJEXT) dwarf_hasform.$(OBJEXT) \
+ dwarf_whatform.$(OBJEXT) dwarf_whatattr.$(OBJEXT) \
+ dwarf_bytesize.$(OBJEXT) dwarf_arrayorder.$(OBJEXT) \
+ dwarf_bitsize.$(OBJEXT) dwarf_bitoffset.$(OBJEXT) \
+ dwarf_srclang.$(OBJEXT) dwarf_getabbrevtag.$(OBJEXT) \
+ dwarf_getabbrevcode.$(OBJEXT) \
dwarf_abbrevhaschildren.$(OBJEXT) dwarf_getattrcnt.$(OBJEXT) \
dwarf_getabbrevattr.$(OBJEXT) dwarf_getsrclines.$(OBJEXT) \
- dwarf_getsrc_die.$(OBJEXT) dwarf_linesrc.$(OBJEXT) \
+ dwarf_getsrc_die.$(OBJEXT) dwarf_getscopes.$(OBJEXT) \
+ dwarf_getscopevar.$(OBJEXT) dwarf_linesrc.$(OBJEXT) \
dwarf_lineno.$(OBJEXT) dwarf_lineaddr.$(OBJEXT) \
dwarf_linecol.$(OBJEXT) dwarf_linebeginstatement.$(OBJEXT) \
dwarf_lineendsequence.$(OBJEXT) dwarf_lineblock.$(OBJEXT) \
@@ -106,9 +110,11 @@ am_libdw_a_OBJECTS = dwarf_begin.$(OBJEXT) dwarf_begin_elf.$(OBJEXT) \
dwarf_func_name.$(OBJEXT) dwarf_func_lowpc.$(OBJEXT) \
dwarf_func_highpc.$(OBJEXT) dwarf_func_entrypc.$(OBJEXT) \
dwarf_func_file.$(OBJEXT) dwarf_func_line.$(OBJEXT) \
- dwarf_func_col.$(OBJEXT) dwarf_getsrc_file.$(OBJEXT) \
+ dwarf_func_col.$(OBJEXT) dwarf_func_die.$(OBJEXT) \
+ dwarf_func_inline.$(OBJEXT) dwarf_getsrc_file.$(OBJEXT) \
libdw_findcu.$(OBJEXT) libdw_form.$(OBJEXT) \
- libdw_alloc.$(OBJEXT)
+ libdw_alloc.$(OBJEXT) memory-access.$(OBJEXT) \
+ libdw_visit_scopes.$(OBJEXT)
libdw_a_OBJECTS = $(am_libdw_a_OBJECTS)
libdw_pic_a_AR = $(AR) $(ARFLAGS)
libdw_pic_a_LIBADD =
@@ -143,19 +149,23 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
-DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DIS_LIBDW
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -164,12 +174,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -245,9 +257,11 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \
dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \
dwarf_attr.c dwarf_formstring.c dwarf_abbrev_hash.c \
+ dwarf_attr_integrate.c dwarf_hasattr_integrate.c \
dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \
dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \
- dwarf_highpc.c dwarf_formref.c dwarf_siblingof.c \
+ dwarf_haspc.c dwarf_highpc.c \
+ dwarf_formref.c dwarf_formref_die.c dwarf_siblingof.c \
dwarf_dieoffset.c dwarf_cuoffset.c dwarf_hasattr.c \
dwarf_hasform.c dwarf_whatform.c dwarf_whatattr.c \
dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \
@@ -255,6 +269,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \
dwarf_getattrcnt.c dwarf_getabbrevattr.c \
dwarf_getsrclines.c dwarf_getsrc_die.c \
+ dwarf_getscopes.c dwarf_getscopevar.c \
dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \
dwarf_linecol.c dwarf_linebeginstatement.c \
dwarf_lineendsequence.c dwarf_lineblock.c \
@@ -268,12 +283,15 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
dwarf_macro_param2.c dwarf_addrdie.c \
dwarf_getfuncs.c dwarf_func_name.c dwarf_func_lowpc.c \
dwarf_func_highpc.c dwarf_func_entrypc.c dwarf_func_file.c \
- dwarf_func_line.c dwarf_func_col.c dwarf_getsrc_file.c \
- libdw_findcu.c libdw_form.c libdw_alloc.c
+ dwarf_func_line.c dwarf_func_col.c dwarf_func_die.c \
+ dwarf_func_inline.c dwarf_getsrc_file.c \
+ libdw_findcu.c libdw_form.c libdw_alloc.c memory-access.c \
+ libdw_visit_scopes.c
@MUDFLAP_FALSE@libdw_pic_a_SOURCES =
@MUDFLAP_FALSE@am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
@MUDFLAP_FALSE@libdw_so_SOURCES =
+libdw_a_LIBADD = $(addprefix ../libdwfl/,$(shell $(AR) t ../libdwfl/libdwfl.a))
noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h
EXTRA_DIST = libdw.map
CLEANFILES = $(am_libdw_pic_a_OBJECTS)
@@ -368,6 +386,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_addrdie.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_arrayorder.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_attr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_attr_integrate.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_begin.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_begin_elf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_bitoffset.Po@am__quote@
@@ -384,13 +403,16 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formblock.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formflag.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formref.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formref_die.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formsdata.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formstring.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formudata.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_col.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_die.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_entrypc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_file.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_highpc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_inline.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_line.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_lowpc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_name.Po@am__quote@
@@ -408,14 +430,18 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getloclist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getmacros.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getpubnames.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getscopes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getscopevar.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrc_die.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrc_file.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrcfiles.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrclines.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getstring.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasattr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasattr_integrate.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_haschildren.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasform.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_haspc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_highpc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineaddr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linebeginstatement.Po@am__quote@
@@ -443,6 +469,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_alloc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_findcu.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_form.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_visit_scopes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory-access.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@@ -666,11 +694,13 @@ uninstall-am: uninstall-euincludeHEADERS uninstall-includeHEADERS \
uninstall-includeHEADERS uninstall-info-am \
uninstall-libLIBRARIES
-@MUDFLAP_FALSE@libdw.so: libdw_pic.a $(srcdir)/libdw.map
-@MUDFLAP_FALSE@ $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-@MUDFLAP_FALSE@ -Wl,--version-script,$(srcdir)/libdw.map,--no-undefined \
-@MUDFLAP_FALSE@ -Wl,--soname,$@.$(VERSION),-z,defs \
-@MUDFLAP_FALSE@ ../libelf/libelf.so
+@MUDFLAP_FALSE@libdw.so: $(srcdir)/libdw.map libdw_pic.a \
+@MUDFLAP_FALSE@ ../libdwfl/libdwfl_pic.a ../libebl/libebl.a \
+@MUDFLAP_FALSE@ ../libelf/libelf.so
+@MUDFLAP_FALSE@ $(CC) -shared -o $@ -Wl,--soname,$@.$(VERSION),-z,defs \
+@MUDFLAP_FALSE@ -Wl,--version-script,$<,--no-undefined \
+@MUDFLAP_FALSE@ -Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive \
+@MUDFLAP_FALSE@ -ldl
@MUDFLAP_FALSE@ if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
@MUDFLAP_FALSE@ ln -fs $@ $@.$(VERSION)
diff --git a/elfutils/libdw/dwarf.h b/elfutils/libdw/dwarf.h
index ce011aac..2268256f 100644
--- a/elfutils/libdw/dwarf.h
+++ b/elfutils/libdw/dwarf.h
@@ -511,7 +511,7 @@ enum
DW_LNS_const_add_pc = 8,
DW_LNS_fixed_advance_pc = 9,
DW_LNS_set_prologue_end = 10,
- DW_LNS_set_epilog_begin = 11,
+ DW_LNS_set_epilogue_begin = 11,
DW_LNS_set_isa = 12
};
diff --git a/elfutils/libdw/dwarf_attr_integrate.c b/elfutils/libdw/dwarf_attr_integrate.c
new file mode 100644
index 00000000..4f95937e
--- /dev/null
+++ b/elfutils/libdw/dwarf_attr_integrate.c
@@ -0,0 +1,45 @@
+/* Return specific DWARF attribute of a DIE, integrating indirections.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+Dwarf_Attribute *
+dwarf_attr_integrate (Dwarf_Die *die, unsigned int search_name,
+ Dwarf_Attribute *result)
+{
+ Dwarf_Die die_mem;
+
+ do
+ {
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, search_name, result);
+ if (attr != NULL)
+ return attr;
+
+ attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin, result);
+ if (attr == NULL)
+ attr = INTUSE(dwarf_attr) (die, DW_AT_specification, result);
+ if (attr == NULL)
+ break;
+
+ die = INTUSE(dwarf_formref_die) (attr, &die_mem);
+ }
+ while (die != NULL);
+
+ return NULL;
+}
+INTDEF (dwarf_attr_integrate)
diff --git a/elfutils/libdw/dwarf_begin_elf.c b/elfutils/libdw/dwarf_begin_elf.c
index a02d509f..427ffc39 100644
--- a/elfutils/libdw/dwarf_begin_elf.c
+++ b/elfutils/libdw/dwarf_begin_elf.c
@@ -42,7 +42,8 @@ static const char dwarf_scnnames[IDX_last][17] =
[IDX_debug_typenames] = ".debug_typenames",
[IDX_debug_varnames] = ".debug_varnames",
[IDX_debug_weaknames] = ".debug_weaknames",
- [IDX_debug_macinfo] = ".debug_macinfo"
+ [IDX_debug_macinfo] = ".debug_macinfo",
+ [IDX_debug_ranges] = ".debug_ranges"
};
#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
diff --git a/elfutils/libdw/dwarf_child.c b/elfutils/libdw/dwarf_child.c
index fc27a0c1..8dbe9179 100644
--- a/elfutils/libdw/dwarf_child.c
+++ b/elfutils/libdw/dwarf_child.c
@@ -29,7 +29,7 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
unsigned int *codep, unsigned int *formp)
{
Dwarf *dbg = die->cu->dbg;
- unsigned char *readp = (unsigned char *) die->addr;
+ const unsigned char *readp = (unsigned char *) die->addr;
/* First we have to get the abbreviation code so that we can decode
the data in the DIE. */
@@ -54,7 +54,7 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
= ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
+ dbg->sectiondata[IDX_debug_abbrev]->d_size);
- unsigned char *attrp = die->abbrev->attrp;
+ const unsigned char *attrp = die->abbrev->attrp;
while (1)
{
/* Are we still in bounds? This test needs to be refined. */
@@ -85,7 +85,7 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
if (formp != NULL)
*formp = attr_form;
- return readp;
+ return (unsigned char *) readp;
}
/* Skip over the rest of this attribute (if there is any). */
@@ -110,7 +110,7 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
if (formp != NULL)
*formp = INVALID;
- return readp;
+ return (unsigned char *) readp;
}
diff --git a/elfutils/libdw/dwarf_end.c b/elfutils/libdw/dwarf_end.c
index 935bd3d2..3328a7ca 100644
--- a/elfutils/libdw/dwarf_end.c
+++ b/elfutils/libdw/dwarf_end.c
@@ -73,3 +73,4 @@ dwarf_end (dwarf)
return 0;
}
+INTDEF(dwarf_end)
diff --git a/elfutils/libdw/dwarf_error.c b/elfutils/libdw/dwarf_error.c
index dfd2171c..291dbc6d 100644
--- a/elfutils/libdw/dwarf_error.c
+++ b/elfutils/libdw/dwarf_error.c
@@ -24,7 +24,7 @@
#ifdef USE_TLS
/* The error number. */
-static int global_error;
+static __thread int global_error;
#else
/* This is the key for the thread specific memory. */
static tls_key_t key;
@@ -65,6 +65,7 @@ dwarf_errno (void)
global_error = DWARF_E_NOERROR;
return result;
}
+INTDEF(dwarf_errno)
/* XXX For now we use string pointers. Once the table stablelizes
@@ -105,6 +106,7 @@ static const char *errmsgs[] =
[DWARF_E_NO_MATCH] = N_("no matching address range"),
[DWARF_E_NO_FLAG] = N_("no flag value"),
[DWARF_E_INVALID_OFFSET] = N_("invalid offset"),
+ [DWARF_E_NO_DEBUG_RANGES] = N_(".debug_ranges section missing"),
};
#define nerrmsgs (sizeof (errmsgs) / sizeof (errmsgs[0]))
@@ -153,6 +155,7 @@ dwarf_errmsg (error)
return _(errmsgs[error == -1 ? last_error : error]);
}
+INTDEF(dwarf_errmsg)
#ifndef USE_TLS
diff --git a/elfutils/libdw/dwarf_formblock.c b/elfutils/libdw/dwarf_formblock.c
index 19169e29..30c2ac93 100644
--- a/elfutils/libdw/dwarf_formblock.c
+++ b/elfutils/libdw/dwarf_formblock.c
@@ -28,8 +28,7 @@ dwarf_formblock (attr, return_block)
if (attr == NULL)
return -1;
- unsigned int u128;
- unsigned char *datap;
+ const unsigned char *datap;
switch (attr->form)
{
@@ -50,9 +49,8 @@ dwarf_formblock (attr, return_block)
case DW_FORM_block:
datap = attr->valp;
- get_uleb128 (u128, datap);
- return_block->length = u128;
- return_block->data = datap;
+ get_uleb128 (return_block->length, datap);
+ return_block->data = (unsigned char *) datap;
break;
default:
diff --git a/elfutils/libdw/dwarf_formref.c b/elfutils/libdw/dwarf_formref.c
index aca74308..ea569905 100644
--- a/elfutils/libdw/dwarf_formref.c
+++ b/elfutils/libdw/dwarf_formref.c
@@ -28,8 +28,7 @@ dwarf_formref (attr, return_offset)
if (attr == NULL)
return -1;
- unsigned int u128;
- unsigned char *datap;
+ const unsigned char *datap;
switch (attr->form)
{
@@ -51,8 +50,7 @@ dwarf_formref (attr, return_offset)
case DW_FORM_ref_udata:
datap = attr->valp;
- get_uleb128 (u128, datap);
- *return_offset = u128;
+ get_uleb128 (*return_offset, datap);
break;
case DW_FORM_ref_addr:
diff --git a/elfutils/libdw/dwarf_formref_die.c b/elfutils/libdw/dwarf_formref_die.c
new file mode 100644
index 00000000..7f5b4f97
--- /dev/null
+++ b/elfutils/libdw/dwarf_formref_die.c
@@ -0,0 +1,28 @@
+/* Look up the DIE in a reference-form attribute.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+Dwarf_Die *
+dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *die_mem)
+{
+ Dwarf_Off offset;
+ return (unlikely (INTUSE(dwarf_formref) (attr, &offset) != 0) ? NULL
+ : INTUSE(dwarf_offdie) (attr->cu->dbg, attr->cu->start + offset,
+ die_mem));
+}
+INTDEF (dwarf_formref_die)
diff --git a/elfutils/libdw/dwarf_formsdata.c b/elfutils/libdw/dwarf_formsdata.c
index 13a785c4..a5b6b88a 100644
--- a/elfutils/libdw/dwarf_formsdata.c
+++ b/elfutils/libdw/dwarf_formsdata.c
@@ -28,8 +28,7 @@ dwarf_formsdata (attr, return_sval)
if (attr == NULL)
return -1;
- unsigned int u128;
- unsigned char *datap;
+ const unsigned char *datap;
switch (attr->form)
{
@@ -51,14 +50,12 @@ dwarf_formsdata (attr, return_sval)
case DW_FORM_sdata:
datap = attr->valp;
- get_sleb128 (u128, datap);
- *return_sval = u128;
+ get_sleb128 (*return_sval, datap);
break;
case DW_FORM_udata:
datap = attr->valp;
- get_uleb128 (u128, datap);
- *return_sval = u128;
+ get_uleb128 (*return_sval, datap);
break;
default:
diff --git a/elfutils/libdw/dwarf_formudata.c b/elfutils/libdw/dwarf_formudata.c
index 5483af81..67985621 100644
--- a/elfutils/libdw/dwarf_formudata.c
+++ b/elfutils/libdw/dwarf_formudata.c
@@ -28,8 +28,7 @@ dwarf_formudata (attr, return_uval)
if (attr == NULL)
return -1;
- unsigned int u128;
- unsigned char *datap;
+ const unsigned char *datap;
switch (attr->form)
{
@@ -51,14 +50,12 @@ dwarf_formudata (attr, return_uval)
case DW_FORM_sdata:
datap = attr->valp;
- get_sleb128 (u128, datap);
- *return_uval = u128;
+ get_sleb128 (*return_uval, datap);
break;
case DW_FORM_udata:
datap = attr->valp;
- get_uleb128 (u128, datap);
- *return_uval = u128;
+ get_uleb128 (*return_uval, datap);
break;
default:
diff --git a/elfutils/libebl/mips_destr.c b/elfutils/libdw/dwarf_func_die.c
index d5007e26..73c65d4d 100644
--- a/elfutils/libebl/mips_destr.c
+++ b/elfutils/libdw/dwarf_func_die.c
@@ -1,6 +1,5 @@
-/* Destructor for MIPS specific backend library.
- Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+/* Get definition DIE of function.
+ Copyright (C) 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -16,12 +15,13 @@
# include <config.h>
#endif
-#include <libebl_mips.h>
+#include <dwarf.h>
+#include "libdwP.h"
-void
-mips_destr (bh)
- Ebl *bh __attribute__ ((unused));
+Dwarf_Die *
+dwarf_func_die (Dwarf_Func *func, Dwarf_Die *die_mem)
{
- /* Nothing to do so far. */
+ *die_mem = *func->die;
+ return die_mem;
}
diff --git a/elfutils/libdw/dwarf_func_inline.c b/elfutils/libdw/dwarf_func_inline.c
new file mode 100644
index 00000000..7656286f
--- /dev/null
+++ b/elfutils/libdw/dwarf_func_inline.c
@@ -0,0 +1,72 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+struct visitor_info
+{
+ void *die_addr;
+ int (*callback) (Dwarf_Die *, void *);
+ void *arg;
+};
+
+static int
+scope_visitor (unsigned int depth __attribute__ ((unused)),
+ Dwarf_Die *die, void *arg)
+{
+ struct visitor_info *const v = arg;
+
+ if (INTUSE(dwarf_tag) (die) != DW_TAG_inlined_subroutine)
+ return DWARF_CB_OK;
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin,
+ &attr_mem);
+ if (attr == NULL)
+ return DWARF_CB_OK;
+
+ Dwarf_Die origin_mem;
+ Dwarf_Die *origin = INTUSE(dwarf_formref_die) (attr, &origin_mem);
+ if (origin == NULL)
+ return DWARF_CB_ABORT;
+
+ if (origin->addr != v->die_addr)
+ return DWARF_CB_OK;
+
+ return (*v->callback) (die, v->arg);
+}
+
+int
+dwarf_func_inline (Dwarf_Func *func)
+{
+ Dwarf_Attribute attr_mem;
+ Dwarf_Word val;
+ if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (func->die, DW_AT_inline,
+ &attr_mem),
+ &val) == 0)
+ switch (val)
+ {
+ case DW_INL_not_inlined:
+ return 0;
+
+ case DW_INL_declared_not_inlined:
+ return -1;
+
+ case DW_INL_inlined:
+ case DW_INL_declared_inlined:
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+dwarf_func_inline_instances (Dwarf_Func *func,
+ int (*callback) (Dwarf_Die *, void *),
+ void *arg)
+{
+ struct visitor_info v = { func->die->addr, callback, arg };
+ return __libdw_visit_scopes (0, func->cudie, &scope_visitor, &v);
+}
diff --git a/elfutils/libdw/dwarf_getabbrev.c b/elfutils/libdw/dwarf_getabbrev.c
index dc89823d..ecac0859 100644
--- a/elfutils/libdw/dwarf_getabbrev.c
+++ b/elfutils/libdw/dwarf_getabbrev.c
@@ -34,8 +34,15 @@ __libdw_getabbrev (dbg, cu, offset, lengthp, result)
if (dbg->sectiondata[IDX_debug_abbrev] == NULL)
return NULL;
- unsigned char *abbrevp
+ if (offset >= dbg->sectiondata[IDX_debug_abbrev]->d_size)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+ return NULL;
+ }
+
+ const unsigned char *abbrevp
= (unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + offset;
+
if (*abbrevp == '\0')
/* We are past the last entry. */
return DWARF_END_ABBREV;
@@ -56,7 +63,7 @@ __libdw_getabbrev (dbg, cu, offset, lengthp, result)
consists of two parts. The first part is an unsigned LEB128
number representing the attribute's name. The second part is
an unsigned LEB128 number representing the attribute's form. */
- unsigned char *start_abbrevp = abbrevp;
+ const unsigned char *start_abbrevp = abbrevp;
unsigned int code;
get_uleb128 (code, abbrevp);
@@ -88,7 +95,7 @@ __libdw_getabbrev (dbg, cu, offset, lengthp, result)
abb->code = code;
get_uleb128 (abb->tag, abbrevp);
abb->has_children = *abbrevp++ == DW_CHILDREN_yes;
- abb->attrp = abbrevp;
+ abb->attrp = (unsigned char *) abbrevp;
abb->offset = offset;
/* Skip over all the attributes and count them while doing so. */
diff --git a/elfutils/libdw/dwarf_getabbrevattr.c b/elfutils/libdw/dwarf_getabbrevattr.c
index d9337aac..8cdf6a3d 100644
--- a/elfutils/libdw/dwarf_getabbrevattr.c
+++ b/elfutils/libdw/dwarf_getabbrevattr.c
@@ -1,5 +1,5 @@
/* Get specific attribute of abbreviation.
- Copyright (C) 2003, 2004 Red Hat, Inc.
+ Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2003.
This program is Open Source software; you can redistribute it and/or
@@ -33,8 +33,8 @@ dwarf_getabbrevattr (abbrev, idx, namep, formp, offsetp)
return -1;
size_t cnt = 0;
- unsigned char *attrp = abbrev->attrp;
- unsigned char *start_attrp;
+ const unsigned char *attrp = abbrev->attrp;
+ const unsigned char *start_attrp;
unsigned int name;
unsigned int form;
diff --git a/elfutils/libdw/dwarf_getarange_addr.c b/elfutils/libdw/dwarf_getarange_addr.c
index 9c6b4cfb..2d0408e4 100644
--- a/elfutils/libdw/dwarf_getarange_addr.c
+++ b/elfutils/libdw/dwarf_getarange_addr.c
@@ -27,10 +27,19 @@ dwarf_getarange_addr (aranges, addr)
if (aranges == NULL)
return NULL;
- for (size_t cnt = 0; cnt < aranges->naranges; ++cnt)
- if (aranges->info[cnt].addr <= addr
- && addr < aranges->info[cnt].addr + aranges->info[cnt].length)
- return &aranges->info[cnt];
+ /* The ranges are sorted by address, so we can use binary search. */
+ size_t l = 0, u = aranges->naranges;
+ while (l < u)
+ {
+ size_t idx = (l + u) / 2;
+ if (addr < aranges->info[idx].addr)
+ u = idx;
+ else if (addr > aranges->info[idx].addr
+ && addr - aranges->info[idx].addr >= aranges->info[idx].length)
+ l = idx + 1;
+ else
+ return &aranges->info[idx];
+ }
__libdw_seterrno (DWARF_E_NO_MATCH);
return NULL;
diff --git a/elfutils/libdw/dwarf_getaranges.c b/elfutils/libdw/dwarf_getaranges.c
index 9cf18e8e..d51ddaeb 100644
--- a/elfutils/libdw/dwarf_getaranges.c
+++ b/elfutils/libdw/dwarf_getaranges.c
@@ -17,8 +17,8 @@
#endif
#include <stdlib.h>
-
-#include <libdwP.h>
+#include <assert.h>
+#include "libdwP.h"
struct arangelist
@@ -27,6 +27,14 @@ struct arangelist
struct arangelist *next;
};
+/* Compare by Dwarf_Arange.addr, given pointers into an array of pointeers. */
+static int
+compare_aranges (const void *a, const void *b)
+{
+ Dwarf_Arange *const *p1 = a, *const *p2 = b;
+ Dwarf_Arange *l1 = *p1, *l2 = *p2;
+ return l1->addr - l2->addr;
+}
int
dwarf_getaranges (dbg, aranges, naranges)
@@ -98,6 +106,10 @@ dwarf_getaranges (dbg, aranges, naranges)
else
offset = read_8ubyte_unaligned_inc (dbg, readp);
+ /* Sanity-check the offset. */
+ if (offset + 4 > dbg->sectiondata[IDX_debug_info]->d_size)
+ goto invalid;
+
unsigned int address_size = *readp++;
if (address_size != 4 && address_size != 8)
goto invalid;
@@ -110,8 +122,6 @@ dwarf_getaranges (dbg, aranges, naranges)
readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
% (2 * address_size));
- //arange_info->offset = offset;
-
while (1)
{
Dwarf_Word range_address;
@@ -148,6 +158,11 @@ dwarf_getaranges (dbg, aranges, naranges)
offset_size = 4;
new_arange->arange.offset = offset + 3 * offset_size - 4 + 3;
+ /* Sanity-check the data. */
+ if (new_arange->arange.offset
+ >= dbg->sectiondata[IDX_debug_info]->d_size)
+ goto invalid;
+
new_arange->next = arangelist;
arangelist = new_arange;
++narangelist;
@@ -163,22 +178,43 @@ dwarf_getaranges (dbg, aranges, naranges)
}
/* Allocate the array for the result. */
- if (naranges != NULL)
- *naranges = narangelist;
- *aranges = libdw_alloc (dbg, Dwarf_Aranges,
- sizeof (Dwarf_Aranges)
- + narangelist * sizeof (Dwarf_Arange), 1);
-
- (*aranges)->dbg = dbg;
- (*aranges)->naranges = narangelist;
-
- while (narangelist-- > 0)
+ void *buf = libdw_alloc (dbg, Dwarf_Aranges,
+ sizeof (Dwarf_Aranges)
+ + narangelist * sizeof (Dwarf_Arange), 1);
+
+ /* First use the buffer for the pointers, and sort the entries.
+ We'll write the pointers in the end of the buffer, and then
+ copy into the buffer from the beginning so the overlap works. */
+ assert (sizeof (Dwarf_Arange) >= sizeof (Dwarf_Arange *));
+ Dwarf_Arange **sortaranges = (buf + sizeof (Dwarf_Aranges)
+ + ((sizeof (Dwarf_Arange)
+ - sizeof (Dwarf_Arange *)) * narangelist));
+
+ /* The list is in LIFO order and usually they come in clumps with
+ ascending addresses. So fill from the back to probably start with
+ runs already in order before we sort. */
+ unsigned int i = narangelist;
+ while (i-- > 0)
{
- (*aranges)->info[narangelist] = arangelist->arange;
+ sortaranges[i] = &arangelist->arange;
arangelist = arangelist->next;
}
+ assert (arangelist == NULL);
+
+ /* Sort by ascending address. */
+ qsort (sortaranges, narangelist, sizeof sortaranges[0], &compare_aranges);
+ /* Now that they are sorted, put them in the final array.
+ The buffers overlap, so we've clobbered the early elements
+ of SORTARANGES by the time we're reading the later ones. */
+ *aranges = buf;
+ (*aranges)->dbg = dbg;
+ (*aranges)->naranges = narangelist;
dbg->aranges = *aranges;
+ if (naranges != NULL)
+ *naranges = narangelist;
+ for (i = 0; i < narangelist; ++i)
+ (*aranges)->info[i] = *sortaranges[i];
return 0;
}
diff --git a/elfutils/libdw/dwarf_getattrs.c b/elfutils/libdw/dwarf_getattrs.c
index 4ead80cc..8e6326d7 100644
--- a/elfutils/libdw/dwarf_getattrs.c
+++ b/elfutils/libdw/dwarf_getattrs.c
@@ -1,5 +1,5 @@
/* Get attributes of the DIE.
- Copyright (C) 2004 Red Hat, Inc.
+ Copyright (C) 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2004.
This program is Open Source software; you can redistribute it and/or
@@ -26,7 +26,7 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
if (die == NULL)
return -1l;
- unsigned char *die_addr = die->addr;
+ const unsigned char *die_addr = die->addr;
/* Get the abbreviation code. */
unsigned int u128;
@@ -43,7 +43,7 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
}
/* This is where the attributes start. */
- unsigned char *attrp = die->abbrev->attrp + offset;
+ const unsigned char *attrp = die->abbrev->attrp + offset;
/* Go over the list of attributes. */
Dwarf *dbg = die->cu->dbg;
@@ -69,7 +69,7 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
return 0;
/* Fill in the rest. */
- attr.valp = die_addr;
+ attr.valp = (unsigned char *) die_addr;
attr.cu = die->cu;
/* Now call the callback function. */
diff --git a/elfutils/libdw/dwarf_getloclist.c b/elfutils/libdw/dwarf_getloclist.c
index 152af649..ab7c3869 100644
--- a/elfutils/libdw/dwarf_getloclist.c
+++ b/elfutils/libdw/dwarf_getloclist.c
@@ -23,6 +23,34 @@
#include <libdwP.h>
+static bool
+attr_ok (Dwarf_Attribute *attr)
+{
+ if (attr == NULL)
+ return false;
+
+ /* Must be one of the attributes listed below. */
+ switch (attr->code)
+ {
+ case DW_AT_location:
+ case DW_AT_data_member_location:
+ case DW_AT_vtable_elem_location:
+ case DW_AT_string_length:
+ case DW_AT_use_location:
+ case DW_AT_frame_base:
+ case DW_AT_return_addr:
+ case DW_AT_static_link:
+ break;
+
+ default:
+ __libdw_seterrno (DWARF_E_NO_LOCLIST);
+ return false;
+ }
+
+ return true;
+}
+
+
struct loclist
{
uint8_t atom;
@@ -47,35 +75,14 @@ loc_compare (const void *p1, const void *p2)
return 0;
}
-
-int
-dwarf_getloclist (attr, llbuf, listlen)
- Dwarf_Attribute *attr;
- Dwarf_Loc **llbuf;
- size_t *listlen;
+static int
+getloclist (struct Dwarf_CU *cu, const Dwarf_Block *block,
+ Dwarf_Loc **llbuf, size_t *listlen)
{
- /* Must by one of the attribute listed below. */
- if (attr->code != DW_AT_location
- && attr->code != DW_AT_data_member_location
- && attr->code != DW_AT_vtable_elem_location
- && attr->code != DW_AT_string_length
- && attr->code != DW_AT_use_location
- && attr->code != DW_AT_return_addr)
- {
- __libdw_seterrno (DWARF_E_NO_LOCLIST);
- return -1;
- }
-
- struct Dwarf_CU *cu = attr->cu;
Dwarf *dbg = cu->dbg;
- /* Must have the form data4 or data8 which act as an offset. */
- Dwarf_Block block;
- if (INTUSE(dwarf_formblock) (attr, &block) != 0)
- return -1;
-
/* Check whether we already looked at this list. */
- struct loc_s fake = { .addr = block.data };
+ struct loc_s fake = { .addr = block->data };
struct loc_s **found = tfind (&fake, &cu->locs, loc_compare);
if (found != NULL)
{
@@ -86,8 +93,8 @@ dwarf_getloclist (attr, llbuf, listlen)
return 0;
}
- unsigned char *data = block.data;
- unsigned char *const end_data = data + block.length;
+ const unsigned char *data = block->data;
+ const unsigned char *const end_data = data + block->length;
struct loclist *loclist = NULL;
unsigned int n = 0;
@@ -99,7 +106,7 @@ dwarf_getloclist (attr, llbuf, listlen)
newloc = (struct loclist *) alloca (sizeof (struct loclist));
newloc->number = 0;
newloc->number2 = 0;
- newloc->offset = data - block.data;
+ newloc->offset = data - block->data;
newloc->next = loclist;
loclist = newloc;
++n;
@@ -286,7 +293,7 @@ dwarf_getloclist (attr, llbuf, listlen)
later. */
struct loc_s *newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s),
1);
- newp->addr = block.data;
+ newp->addr = block->data;
newp->loc = result;
newp->nloc = *listlen;
(void) tsearch (newp, &cu->locs, loc_compare);
@@ -294,3 +301,154 @@ dwarf_getloclist (attr, llbuf, listlen)
/* We did it. */
return 0;
}
+
+int
+dwarf_getloclist (attr, llbuf, listlen)
+ Dwarf_Attribute *attr;
+ Dwarf_Loc **llbuf;
+ size_t *listlen;
+{
+ if (! attr_ok (attr))
+ return -1;
+
+ /* If it has a block form, it's a single location expression. */
+ Dwarf_Block block;
+ if (INTUSE(dwarf_formblock) (attr, &block) != 0)
+ return -1;
+
+ return getloclist (attr->cu, &block, llbuf, listlen);
+}
+
+int
+dwarf_addrloclists (attr, address, llbufs, listlens, maxlocs)
+ Dwarf_Attribute *attr;
+ Dwarf_Addr address;
+ Dwarf_Loc **llbufs;
+ size_t *listlens;
+ size_t maxlocs;
+{
+ if (! attr_ok (attr))
+ return -1;
+
+ if (llbufs == NULL)
+ maxlocs = SIZE_MAX;
+
+ /* If it has a block form, it's a single location expression. */
+ Dwarf_Block block;
+ if (INTUSE(dwarf_formblock) (attr, &block) == 0)
+ {
+ if (maxlocs == 0)
+ return 0;
+ if (llbufs != NULL &&
+ getloclist (attr->cu, &block, &llbufs[0], &listlens[0]) != 0)
+ return -1;
+ return listlens[0] == 0 ? 0 : 1;
+ }
+
+ int error = INTUSE(dwarf_errno) ();
+ if (error != DWARF_E_NO_BLOCK)
+ {
+ __libdw_seterrno (error);
+ return -1;
+ }
+
+ /* Must have the form data4 or data8 which act as an offset. */
+ Dwarf_Word offset;
+ if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
+ return -1;
+
+ const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
+ if (d == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NO_LOCLIST);
+ return -1;
+ }
+
+ /* Fetch the CU's base address. */
+ Dwarf_Addr base;
+ Dwarf_Die cudie =
+ {
+ .cu = attr->cu,
+ .addr = ((char *) attr->cu->dbg->sectiondata[IDX_debug_info]->d_buf
+ + attr->cu->start + 3 * attr->cu->offset_size - 4 + 3),
+ };
+
+
+ /* Find the base address of the compilation unit. It will
+ normally be specified by DW_AT_low_pc. In DWARF-3 draft 4,
+ the base address could be overridden by DW_AT_entry_pc. It's
+ been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
+ for compilation units with discontinuous ranges. */
+ Dwarf_Attribute attr_mem;
+ if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0
+ && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, DW_AT_entry_pc,
+ &attr_mem),
+ &base) != 0)
+ return -1;
+
+ unsigned char *readp = d->d_buf + offset;
+ size_t got = 0;
+ while (got < maxlocs)
+ {
+ if ((unsigned char *) d->d_buf + d->d_size - readp
+ < attr->cu->address_size * 2)
+ {
+ invalid:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+ if (attr->cu->address_size == 8)
+ {
+ begin = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
+ end = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
+
+ if (begin == (Elf64_Addr) -1l) /* Base address entry. */
+ {
+ base = end;
+ continue;
+ }
+ }
+ else
+ {
+ begin = read_4ubyte_unaligned_inc (attr->cu->dbg, readp);
+ end = read_4ubyte_unaligned_inc (attr->cu->dbg, readp);
+
+ if (begin == (Elf32_Addr) -1) /* Base address entry. */
+ {
+ base = end;
+ continue;
+ }
+ }
+
+ if (begin == 0 && end == 0) /* End of list entry. */
+ break;
+
+ if ((unsigned char *) d->d_buf + d->d_size - readp < 2)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+
+ /* We have a location expression. */
+ block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
+ block.data = readp;
+ if ((unsigned char *) d->d_buf + d->d_size - readp
+ < (ptrdiff_t) block.length)
+ goto invalid;
+ readp += block.length;
+
+ if (address >= base + begin && address < base + end)
+ {
+ /* This one matches the address. */
+ if (llbufs != NULL && getloclist (attr->cu, &block,
+ &llbufs[got], &listlens[got]) != 0)
+ return -1;
+ ++got;
+ }
+ }
+
+ return got;
+}
diff --git a/elfutils/libdw/dwarf_getmacros.c b/elfutils/libdw/dwarf_getmacros.c
index c1abdcec..d3678c99 100644
--- a/elfutils/libdw/dwarf_getmacros.c
+++ b/elfutils/libdw/dwarf_getmacros.c
@@ -85,6 +85,11 @@ dwarf_getmacros (die, callback, arg, offset)
break;
case DW_MACINFO_end_file:
+ /* No parameters for this one. */
+ u128 = 0;
+ break;
+
+ case 0:
/* Nothing more to do. */
return 0;
diff --git a/elfutils/libdw/dwarf_getscopes.c b/elfutils/libdw/dwarf_getscopes.c
new file mode 100644
index 00000000..7863036b
--- /dev/null
+++ b/elfutils/libdw/dwarf_getscopes.c
@@ -0,0 +1,343 @@
+/* Return scope DIEs containing PC address.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+enum die_class { ignore, match, match_inline, walk, imported };
+
+static enum die_class
+classify_die (Dwarf_Die *die)
+{
+ switch (INTUSE(dwarf_tag) (die))
+ {
+ /* DIEs with addresses we can try to match. */
+ case DW_TAG_compile_unit:
+ case DW_TAG_module:
+ case DW_TAG_lexical_block:
+ case DW_TAG_with_stmt:
+ case DW_TAG_catch_block:
+ case DW_TAG_try_block:
+ case DW_TAG_entry_point:
+ return match;
+ case DW_TAG_inlined_subroutine:
+ return match_inline;
+ case DW_TAG_subprogram:
+ /* This might be a concrete out-of-line instance of an inline, in
+ which case it is not guaranteed to be owned by the right scope and
+ we will search for its origin as for DW_TAG_inlined_subroutine. */
+ return (INTUSE(dwarf_hasattr) (die, DW_AT_abstract_origin)
+ ? match_inline : match);
+
+ /* DIEs without addresses that can own DIEs with addresses. */
+ case DW_TAG_namespace:
+ return walk;
+
+ /* Special indirection required. */
+ case DW_TAG_imported_unit:
+ return imported;
+
+ /* Other DIEs we have no reason to descend. */
+ default:
+ break;
+ }
+ return ignore;
+}
+
+/* DIE contains PC. Find its child that contains PC. Returns -1 for
+ errors, 0 for no matches. On success, *SCOPES gets the malloc'd array
+ of containing scopes. A positive return value is the number of those
+ scopes. A return value < -1 is -1 - number of those scopes, when the
+ outermost scope is a concrete instance of an inline subroutine. */
+static int
+find_pc (unsigned int depth, Dwarf_Die *die, Dwarf_Addr pc, Dwarf_Die **scopes)
+{
+ Dwarf_Die child;
+ if (INTUSE(dwarf_child) (die, &child) != 0)
+ return -1;
+
+ /* Recurse on this DIE to search within its children.
+ Return nonzero if this gets an error or a final result. */
+ inline int search_child (void)
+ {
+ int n = find_pc (depth + 1, &child, pc, scopes);
+ if (n > 0)
+ /* That stored the N innermost scopes. Now store ours. */
+ (*scopes)[n++] = child;
+ return n;
+ }
+
+ /* Check each of our child DIEs. */
+ enum die_class got = ignore;
+ do
+ {
+ enum die_class child_class = classify_die (&child);
+ switch (child_class)
+ {
+ case match:
+ case match_inline:
+ if (INTUSE(dwarf_haspc) (&child, pc) > 0)
+ break;
+ continue;
+
+ case walk:
+ if (INTUSE(dwarf_haschildren) (&child))
+ got = walk;
+ continue;
+
+ case imported:
+ got = walk;
+ continue;
+
+ default:
+ case ignore:
+ continue;
+ }
+
+ /* We get here only when the PC has matched. */
+ got = child_class;
+ break;
+ }
+ while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
+
+ switch (got)
+ {
+ case match:
+ case match_inline:
+ /* We have a DIE that matched the PC. */
+ if (INTUSE(dwarf_haschildren) (&child))
+ {
+ /* Recurse on this DIE to narrow within its children.
+ Return now if this gets an error or a final result. */
+ int result = search_child ();
+ if (result < 0 || (got == match && result > 0))
+ return result;
+ if (result > 0) /* got == match_inline */
+ /* We have a winner, but CHILD is a concrete inline instance
+ so DIE and its containing scopes do not actually apply.
+ DIE is the scope that inlined the function. Our root
+ caller must find the abstract scope that defines us. */
+ return -1 - result;
+ }
+
+ /* This DIE has no children containing the PC, so this is it. */
+ *scopes = malloc (depth * sizeof (*scopes)[0]);
+ if (*scopes == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return -1;
+ }
+ (*scopes)[0] = child;
+ return got == match ? 1 : -2;
+
+ case walk:
+ /* We don't have anything matching the PC, but we have some things
+ we might descend to find one. Recurse on each of those. */
+ if (INTUSE(dwarf_child) (die, &child) != 0)
+ return -1;
+ do
+ switch (classify_die (&child))
+ {
+ case walk:
+ if (INTUSE(dwarf_haschildren) (&child))
+ {
+ /* Recurse on this DIE to look for the PC within its children.
+ Return now if this gets an error or a final result. */
+ int result = search_child ();
+ if (result != 0)
+ return result;
+ }
+ break;
+
+ case imported:
+ {
+ /* This imports another compilation unit to appear
+ as part of this one, inside the current scope.
+ Recurse to search the referenced unit, but without
+ recording it as an inner scoping level. */
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child, DW_AT_import,
+ &attr_mem);
+ if (INTUSE(dwarf_formref_die) (attr, &child) != NULL)
+ {
+ int result = find_pc (depth, &child, pc, scopes);
+ if (result != 0)
+ return result;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
+ break;
+
+ default:
+ case ignore:
+ /* Nothing to see here. */
+ break;
+ }
+
+ /* No matches. */
+ return 0;
+}
+
+
+/* OWNER owns OWNED. Find intermediate scopes. *SCOPES was allocated by
+ find_pc and has SKIP elements. We realloc it, append more containing
+ scopes, and return 1 + the number appended. Returns -1 on errors,
+ or 0 when OWNED was not found within OWNER. */
+static int
+find_die (unsigned int depth, Dwarf_Die *owner, Dwarf_Die *owned,
+ Dwarf_Die **scopes, unsigned int skip)
+{
+ Dwarf_Die child;
+ if (INTUSE(dwarf_child) (owner, &child) != 0)
+ return -1;
+
+ do
+ {
+ if (child.addr == owned->addr)
+ /* This is the one. OWNER is the innermost owner. */
+ return 1;
+
+ /* Unfortunately we cannot short-circuit the dead-end paths just by
+ checking the physical layout to see if OWNED falls within CHILD.
+ If it doesn't, there may still be a DW_TAG_imported_unit that
+ refers to its true owner indirectly. */
+
+ switch (classify_die (&child))
+ {
+ case match:
+ case match_inline:
+ case walk:
+ if (INTUSE(dwarf_haschildren) (&child))
+ {
+ /* Recurse on this DIE to look for OWNED within its children.
+ Return now if this gets an error or a final result. */
+ int n = find_die (depth + 1, &child, owned, scopes, skip);
+ if (n < 0)
+ return n;
+ if (n > 1)
+ {
+ /* We have a winner. CHILD owns the owner of OWNED. */
+ (*scopes)[skip + n - 1] = child;
+ return n + 1;
+ }
+ if (n > 0) /* n == 1 */
+ {
+ /* CHILD is the direct owner of OWNED. */
+ Dwarf_Die *nscopes = realloc (*scopes,
+ (skip + depth)
+ * sizeof nscopes[0]);
+ if (nscopes == NULL)
+ {
+ free (*scopes);
+ *scopes = NULL;
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return -1;
+ }
+ nscopes[skip] = child;
+ *scopes = nscopes;
+ return 2;
+ }
+ }
+ break;
+
+ case imported:
+ {
+ /* This is imports another compilation unit to appear
+ as part of this one, inside the current scope.
+ Recurse to search the referenced unit, but without
+ recording it as an inner scoping level. */
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child, DW_AT_import,
+ &attr_mem);
+ if (INTUSE(dwarf_formref_die) (attr, &child) != NULL)
+ {
+ int result = find_die (depth, &child, owner, scopes, skip);
+ if (result != 0)
+ return result;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
+
+ return 0;
+}
+
+
+int
+dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc, Dwarf_Die **scopes)
+{
+ if (cudie == NULL)
+ return -1;
+
+ int n = find_pc (2, cudie, pc, scopes);
+ if (likely (n >= 0))
+ {
+ /* We have a final result. Now store the outermost scope, the CU. */
+ (*scopes)[n++] = *cudie;
+ return n;
+ }
+ if (n == -1)
+ return n;
+
+ /* We have the scopes out to one that is a concrete instance of an
+ inlined subroutine (usually DW_TAG_inlined_subroutine, but can
+ be DW_TAG_subprogram for a concrete out-of-line instance).
+ Now we must find the lexical scopes that contain the
+ corresponding abstract inline subroutine definition. */
+
+ n = -n - 1;
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Die die_mem;
+ Dwarf_Die *origin = INTUSE(dwarf_formref_die)
+ (INTUSE(dwarf_attr) (&(*scopes)[n - 1], DW_AT_abstract_origin, &attr_mem),
+ &die_mem);
+ if (unlikely (origin == NULL))
+ goto invalid;
+
+ int result = find_die (0, cudie, origin, scopes, n);
+ if (likely (result > 0))
+ {
+ n = n + result - 1;
+ (*scopes)[n++] = *cudie;
+ return n;
+ }
+
+ if (result == 0) /* No match, shouldn't happen. */
+ {
+ invalid:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ }
+
+ free (*scopes);
+ *scopes = NULL;
+ return -1;
+}
diff --git a/elfutils/libdw/dwarf_getscopevar.c b/elfutils/libdw/dwarf_getscopevar.c
new file mode 100644
index 00000000..3ceb292d
--- /dev/null
+++ b/elfutils/libdw/dwarf_getscopevar.c
@@ -0,0 +1,147 @@
+/* Find a named variable or parameter within given scopes.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <string.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+/* Find the containing CU's files. */
+static int
+getfiles (Dwarf_Die *die, Dwarf_Files **files)
+{
+ Dwarf_Die cudie =
+ {
+ .cu = die->cu,
+ .addr = ((char *) die->cu->dbg->sectiondata[IDX_debug_info]->d_buf
+ + 3 * die->cu->offset_size - 4 + 3),
+ };
+ return INTUSE(dwarf_getsrcfiles) (&cudie, files, NULL);
+}
+
+/* Fetch an attribute that should have a constant integer form. */
+static int
+getattr (Dwarf_Die *die, int search_name, Dwarf_Word *value)
+{
+ Dwarf_Attribute attr_mem;
+ return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (die, search_name,
+ &attr_mem), value);
+}
+
+/* Search SCOPES[0..NSCOPES-1] for a variable called NAME.
+ Ignore the first SKIP_SHADOWS scopes that match the name.
+ If MATCH_FILE is not null, accept only declaration in that source file;
+ if MATCH_LINENO or MATCH_LINECOL are also nonzero, accept only declaration
+ at that line and column.
+
+ If successful, fill in *RESULT with the DIE of the variable found,
+ and return N where SCOPES[N] is the scope defining the variable.
+ Return -1 for errors or -2 for no matching variable found. */
+
+int
+dwarf_getscopevar (Dwarf_Die *scopes, int nscopes,
+ const char *name, int skip_shadows,
+ const char *match_file, int match_lineno, int match_linecol,
+ Dwarf_Die *result)
+{
+ /* Match against the given file name. */
+ size_t match_file_len = match_file == NULL ? 0 : strlen (match_file);
+ bool lastfile_matches = false;
+ const char *lastfile = NULL;
+ inline bool file_matches (Dwarf_Files *files, size_t idx)
+ {
+ if (idx >= files->nfiles)
+ return false;
+
+ const char *file = files->info[idx].name;
+ if (file != lastfile)
+ {
+ size_t len = strlen (file);
+ lastfile_matches = (len >= match_file_len
+ && !memcmp (match_file, file, match_file_len)
+ && (len == match_file_len
+ || file[len - match_file_len - 1] == '/'));
+ }
+ return lastfile_matches;
+ }
+
+ /* Start with the innermost scope and move out. */
+ for (int out = 0; out < nscopes; ++out)
+ if (INTUSE(dwarf_haschildren) (&scopes[out]))
+ {
+ if (INTUSE(dwarf_child) (&scopes[out], result) != 0)
+ return -1;
+ do
+ {
+ switch (INTUSE(dwarf_tag) (result))
+ {
+ case DW_TAG_variable:
+ case DW_TAG_formal_parameter:
+ break;
+
+ default:
+ continue;
+ }
+
+ /* Only get here for a variable or parameter. Check the name. */
+ Dwarf_Attribute attr_mem;
+ const char *diename = INTUSE(dwarf_formstring)
+ (INTUSE(dwarf_attr_integrate) (result, DW_AT_name, &attr_mem));
+ if (diename != NULL && !strcmp (name, diename))
+ {
+ /* We have a matching name. */
+
+ if (skip_shadows > 0)
+ {
+ /* Punt this scope for the one it shadows. */
+ --skip_shadows;
+ break;
+ }
+
+ if (match_file != NULL)
+ {
+ /* Check its decl_file. */
+
+ Dwarf_Word i;
+ Dwarf_Files *files;
+ if (getattr (result, DW_AT_decl_file, &i) != 0
+ || getfiles (&scopes[out], &files) != 0)
+ break;
+
+ if (!file_matches (files, i))
+ break;
+
+ if (match_lineno > 0
+ && (getattr (result, DW_AT_decl_line, &i) != 0
+ || (int) i != match_lineno))
+ break;
+ if (match_linecol > 0
+ && (getattr (result, DW_AT_decl_column, &i) != 0
+ || (int) i != match_linecol))
+ break;
+ }
+
+ /* We have a winner! */
+ return out;
+ }
+ }
+ while (INTUSE(dwarf_siblingof) (result, result) == 0);
+ }
+
+ return -2;
+}
diff --git a/elfutils/libdw/dwarf_getsrcfiles.c b/elfutils/libdw/dwarf_getsrcfiles.c
index 334c27b6..6472bf44 100644
--- a/elfutils/libdw/dwarf_getsrcfiles.c
+++ b/elfutils/libdw/dwarf_getsrcfiles.c
@@ -57,3 +57,4 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
return res;
}
+INTDEF (dwarf_getsrcfiles)
diff --git a/elfutils/libdw/dwarf_getsrclines.c b/elfutils/libdw/dwarf_getsrclines.c
index 74a591c3..85fe35eb 100644
--- a/elfutils/libdw/dwarf_getsrclines.c
+++ b/elfutils/libdw/dwarf_getsrclines.c
@@ -36,7 +36,7 @@ struct linelist
};
-/* Compare by Dwarf_Line.addr, given pointers into an array of pointeers. */
+/* Compare by Dwarf_Line.addr, given pointers into an array of pointers. */
static int
compare_lines (const void *a, const void *b)
{
@@ -105,9 +105,9 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
__libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
goto out;
}
- uint8_t *linep = dbg->sectiondata[IDX_debug_line]->d_buf + offset;
- uint8_t *lineendp = (dbg->sectiondata[IDX_debug_line]->d_buf
- + dbg->sectiondata[IDX_debug_line]->d_size);
+ const uint8_t *linep = dbg->sectiondata[IDX_debug_line]->d_buf + offset;
+ const uint8_t *lineendp = (dbg->sectiondata[IDX_debug_line]->d_buf
+ + dbg->sectiondata[IDX_debug_line]->d_size);
/* Get the compilation directory. */
Dwarf_Attribute compdir_attr_mem;
@@ -152,7 +152,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
header_length = read_4ubyte_unaligned_inc (dbg, linep);
else
header_length = read_8ubyte_unaligned_inc (dbg, linep);
- unsigned char *header_start = linep;
+ const unsigned char *header_start = linep;
/* Next the minimum instruction length. */
uint_fast8_t minimum_instr_len = *linep++;
@@ -173,7 +173,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
/* Remember array with the standard opcode length (-1 to account for
the opcode with value zero not being mentioned). */
- uint8_t *standard_opcode_lengths = linep - 1;
+ const uint8_t *standard_opcode_lengths = linep - 1;
linep += opcode_base - 1;
if (unlikely (linep >= lineendp))
goto invalid_data;
@@ -450,7 +450,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
break;
}
}
- else if (opcode <= DW_LNS_set_epilog_begin)
+ else if (opcode <= DW_LNS_set_epilogue_begin)
{
/* This is a known standard opcode. */
switch (opcode)
@@ -553,7 +553,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
prologue_end = 1;
break;
- case DW_LNS_set_epilog_begin:
+ case DW_LNS_set_epilogue_begin:
/* Takes no argument. */
if (unlikely (standard_opcode_lengths[opcode] != 0))
goto invalid_data;
diff --git a/elfutils/libdw/dwarf_hasattr.c b/elfutils/libdw/dwarf_hasattr.c
index 15ad8daa..88dbee49 100644
--- a/elfutils/libdw/dwarf_hasattr.c
+++ b/elfutils/libdw/dwarf_hasattr.c
@@ -1,5 +1,5 @@
/* Check whether given DIE has specific attribute.
- Copyright (C) 2003 Red Hat, Inc.
+ Copyright (C) 2003, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2003.
This program is Open Source software; you can redistribute it and/or
@@ -34,3 +34,4 @@ dwarf_hasattr (die, search_name)
return code == search_name;
}
+INTDEF (dwarf_hasattr)
diff --git a/elfutils/libdw/dwarf_hasattr_integrate.c b/elfutils/libdw/dwarf_hasattr_integrate.c
new file mode 100644
index 00000000..423aa2a2
--- /dev/null
+++ b/elfutils/libdw/dwarf_hasattr_integrate.c
@@ -0,0 +1,42 @@
+/* Check whether DIE has specific attribute, integrating DW_AT_abstract_origin.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+int
+dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name)
+{
+ Dwarf_Die die_mem;
+
+ do
+ {
+ if (INTUSE(dwarf_hasattr) (die, search_name))
+ return 1;
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin,
+ &attr_mem);
+ if (attr == NULL)
+ break;
+
+ die = INTUSE(dwarf_formref_die) (attr, &die_mem);
+ }
+ while (die != NULL);
+
+ return 0;
+}
diff --git a/elfutils/libdw/dwarf_haschildren.c b/elfutils/libdw/dwarf_haschildren.c
index 2a9fe5ff..05a5b526 100644
--- a/elfutils/libdw/dwarf_haschildren.c
+++ b/elfutils/libdw/dwarf_haschildren.c
@@ -1,5 +1,5 @@
/* Return string associated with given attribute.
- Copyright (C) 2003 Red Hat, Inc.
+ Copyright (C) 2003, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2003.
This program is Open Source software; you can redistribute it and/or
@@ -28,7 +28,7 @@ dwarf_haschildren (die)
Dwarf_Abbrev *abbrevp = die->abbrev;
if (abbrevp != (Dwarf_Abbrev *) -1l)
{
- unsigned char *readp = (unsigned char *) die->addr;
+ const unsigned char *readp = (unsigned char *) die->addr;
/* First we have to get the abbreviation code so that we can decode
the data in the DIE. */
@@ -46,3 +46,4 @@ dwarf_haschildren (die)
return die->abbrev->has_children;
}
+INTDEF (dwarf_haschildren)
diff --git a/elfutils/libdw/dwarf_haspc.c b/elfutils/libdw/dwarf_haspc.c
new file mode 100644
index 00000000..7f29296d
--- /dev/null
+++ b/elfutils/libdw/dwarf_haspc.c
@@ -0,0 +1,105 @@
+/* Determine whether a DIE covers a PC address.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+int
+dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc)
+{
+ if (die == NULL)
+ return -1;
+
+ /* Usually there is a single contiguous range. */
+ Dwarf_Addr lowpc, highpc;
+ if (INTUSE(dwarf_highpc) (die, &highpc) == 0
+ && INTUSE(dwarf_lowpc) (die, &lowpc) == 0)
+ return pc >= lowpc && pc < highpc;
+
+ /* We have to look for a noncontiguous range. */
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges, &attr_mem);
+ if (attr == NULL)
+ return -1;
+
+ /* Must have the form data4 or data8 which act as an offset. */
+ Dwarf_Word offset;
+ if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
+ return -1;
+
+ const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_ranges];
+ if (d == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
+ return -1;
+ }
+
+ /* Fetch the CU's base address. */
+ Dwarf_Addr base;
+ Dwarf_Die cudie =
+ {
+ .cu = attr->cu,
+ .addr = ((char *) attr->cu->dbg->sectiondata[IDX_debug_info]->d_buf
+ + attr->cu->start + 3 * attr->cu->offset_size - 4 + 3),
+ };
+ if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
+ return -1;
+
+ unsigned char *readp = d->d_buf + offset;
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+ do
+ {
+ next:
+ if ((unsigned char *) d->d_buf + d->d_size - readp
+ < attr->cu->address_size * 2)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+
+ if (attr->cu->address_size == 8)
+ {
+ begin = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
+ end = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
+ }
+ else
+ {
+ begin = (Dwarf_Sword) read_4sbyte_unaligned_inc (attr->cu->dbg,
+ readp);
+ end = read_4ubyte_unaligned_inc (attr->cu->dbg, readp);
+ }
+
+ if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
+ {
+ base = end;
+ goto next;
+ }
+
+ if (begin == 0 && end == 0) /* End of list entry. */
+ /* This is not the droid you are looking for. */
+ return 0;
+
+ /* We have an address range entry. */
+ }
+ while (pc < base + begin || pc >= base + end);
+
+ /* This one matches the address. */
+ return 1;
+}
+INTDEF (dwarf_haspc)
diff --git a/elfutils/libdw/dwarf_tag.c b/elfutils/libdw/dwarf_tag.c
index a47cfeae..939b6811 100644
--- a/elfutils/libdw/dwarf_tag.c
+++ b/elfutils/libdw/dwarf_tag.c
@@ -64,7 +64,7 @@ dwarf_tag (die)
{
/* Get the abbreviation code. */
unsigned int u128;
- unsigned char *addr = die->addr;
+ const unsigned char *addr = die->addr;
get_uleb128 (u128, addr);
/* Find the abbreviation. */
diff --git a/elfutils/libdw/libdw.h b/elfutils/libdw/libdw.h
index 860212f5..e6b30597 100644
--- a/elfutils/libdw/libdw.h
+++ b/elfutils/libdw/libdw.h
@@ -226,6 +226,16 @@ extern Dwarf_Attribute *dwarf_attr (Dwarf_Die *die, unsigned int search_name,
/* Check whether given DIE has specific attribute. */
extern int dwarf_hasattr (Dwarf_Die *die, unsigned int search_name);
+/* These are the same as dwarf_attr and dwarf_hasattr, respectively,
+ but they resolve an indirect attribute through DW_AT_abstract_origin. */
+extern Dwarf_Attribute *dwarf_attr_integrate (Dwarf_Die *die,
+ unsigned int search_name,
+ Dwarf_Attribute *result)
+ __nonnull_attribute__ (3);
+extern int dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name);
+
+
+
/* Check whether given attribute has specific form. */
extern int dwarf_hasform (Dwarf_Attribute *attr, unsigned int search_form);
@@ -256,6 +266,10 @@ extern int dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
extern int dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
__nonnull_attribute__ (2);
+/* Look up the DIE in a reference-form attribute. */
+extern Dwarf_Die *dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *die_mem)
+ __nonnull_attribute__ (2);
+
/* Return block represented by attribute. */
extern int dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block)
__nonnull_attribute__ (2);
@@ -278,6 +292,10 @@ extern int dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
extern int dwarf_lowpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
__nonnull_attribute__ (2);
+/* Return 1 if DIE's lowpc/highpc or ranges attributes match the PC address,
+ 0 if not, or -1 for errors. */
+extern int dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc);
+
/* Return byte size attribute of DIE. */
extern int dwarf_bytesize (Dwarf_Die *die);
@@ -402,6 +420,43 @@ extern const char *dwarf_filesrc (Dwarf_Files *file, size_t idx,
extern int dwarf_getloclist (Dwarf_Attribute *attr, Dwarf_Loc **llbuf,
size_t *listlen) __nonnull_attribute__ (2, 3);
+/* Return location expression lists. If the attribute uses a location
+ list, ADDRESS selects the relevant location expressions from the list.
+ There can be multiple matches, resulting in multiple expressions to
+ return. LLBUFS and LISTLENS are parallel arrays of NLOCS slots to fill
+ in. Returns the number of locations filled in, or -1 for errors. If
+ LLBUFS is a null pointer, stores nothing and returns the total number of
+ locations. A return value of zero means that the location list
+ indicated no value is accessible. */
+extern int dwarf_addrloclists (Dwarf_Attribute *attr, Dwarf_Addr address,
+ Dwarf_Loc **llbufs, size_t *listlens,
+ size_t nlocs);
+
+
+/* Return scope DIEs containing PC address.
+ Sets *SCOPES to a malloc'd array of Dwarf_Die structures,
+ and returns the number of elements in the array.
+ (*SCOPES)[0] is the DIE for the innermost scope containing PC,
+ (*SCOPES)[1] is the DIE for the scope containing that scope, and so on.
+ Returns -1 for errors or 0 if no scopes match PC. */
+extern int dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc,
+ Dwarf_Die **scopes);
+
+/* Search SCOPES[0..NSCOPES-1] for a variable called NAME.
+ Ignore the first SKIP_SHADOWS scopes that match the name.
+ If MATCH_FILE is not null, accept only declaration in that source file;
+ if MATCH_LINENO or MATCH_LINECOL are also nonzero, accept only declaration
+ at that line and column.
+
+ If successful, fill in *RESULT with the DIE of the variable found,
+ and return N where SCOPES[N] is the scope defining the variable.
+ Return -1 for errors or -2 for no matching variable found. */
+extern int dwarf_getscopevar (Dwarf_Die *scopes, int nscopes,
+ const char *name, int skip_shadows,
+ const char *match_file,
+ int match_lineno, int match_linecol,
+ Dwarf_Die *result);
+
/* Return list address ranges. */
@@ -453,6 +508,19 @@ extern int dwarf_func_line (Dwarf_Func *func, int *linep)
extern int dwarf_func_col (Dwarf_Func *func, int *colp)
__nonnull_attribute__ (2);
+/* Get definition DIE of given function. */
+extern Dwarf_Die *dwarf_func_die (Dwarf_Func *func, Dwarf_Die *die_mem)
+ __nonnull_attribute__ (2);
+
+/* Return nonzero if given function is an abstract inline definition. */
+extern int dwarf_func_inline (Dwarf_Func *func);
+
+/* Find each concrete inlined instance of the abstract inline definition. */
+extern int dwarf_func_inline_instances (Dwarf_Func *func,
+ int (*callback) (Dwarf_Die *, void *),
+ void *arg);
+
+
/* Call callback function for each of the macro information entry for
the CU. */
diff --git a/elfutils/libdw/libdw.map b/elfutils/libdw/libdw.map
index eb224ba4..01ee5f60 100644
--- a/elfutils/libdw/libdw.map
+++ b/elfutils/libdw/libdw.map
@@ -1,8 +1,11 @@
-ELFUTILS_1.0 {
+ELFUTILS_0 { };
+ELFUTILS_0.114 {
global:
dwarf_abbrevhaschildren;
dwarf_addrdie;
+ dwarf_addrloclists;
dwarf_attr;
+ dwarf_attr_integrate;
dwarf_arrayorder;
dwarf_begin;
dwarf_begin_elf;
@@ -21,13 +24,17 @@ ELFUTILS_1.0 {
dwarf_formblock;
dwarf_formflag;
dwarf_formref;
+ dwarf_formref_die;
dwarf_formsdata;
dwarf_formstring;
dwarf_formudata;
dwarf_func_col;
+ dwarf_func_die;
dwarf_func_entrypc;
dwarf_func_file;
dwarf_func_highpc;
+ dwarf_func_inline;
+ dwarf_func_inline_instances;
dwarf_func_line;
dwarf_func_lowpc;
dwarf_func_name;
@@ -45,6 +52,8 @@ ELFUTILS_1.0 {
dwarf_getloclist;
dwarf_getmacros;
dwarf_getpubnames;
+ dwarf_getscopes;
+ dwarf_getscopevar;
dwarf_getscn_info;
dwarf_getsrc_die;
dwarf_getsrc_file;
@@ -52,6 +61,8 @@ ELFUTILS_1.0 {
dwarf_getsrclines;
dwarf_getstring;
dwarf_hasattr;
+ dwarf_hasattr_integrate;
+ dwarf_haspc;
dwarf_haschildren;
dwarf_hasform;
dwarf_highpc;
@@ -80,6 +91,50 @@ ELFUTILS_1.0 {
dwarf_whatattr;
dwarf_whatform;
+ # libdwfl_pic.a contributes these symbols.
+ dwfl_addrdie;
+ dwfl_addrdwarf;
+ dwfl_addrmodule;
+ dwfl_begin;
+ dwfl_cumodule;
+ dwfl_end;
+ dwfl_errmsg;
+ dwfl_errno;
+ dwfl_getdwarf;
+ dwfl_getmodules;
+ dwfl_getsrc;
+ dwfl_getsrclines;
+ dwfl_lineinfo;
+ dwfl_linemodule;
+ dwfl_linux_kernel_find_elf;
+ dwfl_linux_kernel_module_section_address;
+ dwfl_linux_kernel_report_kernel;
+ dwfl_linux_kernel_report_modules;
+ dwfl_linux_kernel_report_offline;
+ dwfl_linux_proc_find_elf;
+ dwfl_linux_proc_report;
+ dwfl_module_addrdie;
+ dwfl_module_addrname;
+ dwfl_module_getdwarf;
+ dwfl_module_getelf;
+ dwfl_module_getsrc;
+ dwfl_module_getsrc_file;
+ dwfl_module_info;
+ dwfl_module_nextcu;
+ dwfl_module_relocate_address;
+ dwfl_module_relocation_info;
+ dwfl_module_relocations;
+ dwfl_nextcu;
+ dwfl_offline_section_address;
+ dwfl_onesrcline;
+ dwfl_report_begin;
+ dwfl_report_elf;
+ dwfl_report_end;
+ dwfl_report_module;
+ dwfl_report_offline;
+ dwfl_standard_argp;
+ dwfl_standard_find_debuginfo;
+
local:
*;
-};
+} ELFUTILS_0;
diff --git a/elfutils/libdw/libdwP.h b/elfutils/libdw/libdwP.h
index 669e7455..5f15cf9d 100644
--- a/elfutils/libdw/libdwP.h
+++ b/elfutils/libdw/libdwP.h
@@ -57,6 +57,7 @@ enum
IDX_debug_varnames,
IDX_debug_weaknames,
IDX_debug_macinfo,
+ IDX_debug_ranges,
IDX_last
};
@@ -98,6 +99,7 @@ enum
DWARF_E_NO_MATCH,
DWARF_E_NO_FLAG,
DWARF_E_INVALID_OFFSET,
+ DWARF_E_NO_DEBUG_RANGES,
};
@@ -325,7 +327,8 @@ extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
/* Helper functions for form handling. */
extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
- unsigned int form, unsigned char *valp)
+ unsigned int form,
+ const unsigned char *valp)
__nonnull_attribute__ (1, 2, 4) internal_function;
/* Helper function to locate attribute. */
@@ -339,61 +342,46 @@ extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
extern int __libdw_func_intval (Dwarf_Func *func, int *linep, int attval)
__nonnull_attribute__ (1, 2) internal_function;
+/* Helper function to walk scopes. */
+extern int __libdw_visit_scopes (unsigned int depth, Dwarf_Die *root,
+ int (*visit) (unsigned int depth,
+ Dwarf_Die *die, void *arg),
+ void *arg)
+ __nonnull_attribute__ (2, 3) internal_function;
+
+/* Return error code of last failing function call. This value is kept
+ separately for each thread. */
+extern int __dwarf_errno_internal (void);
-/* Aliases to avoid PLTs. */
-extern Dwarf *__dwarf_begin_elf_internal (Elf *elf, Dwarf_Cmd cmd,
- Elf_Scn *scngrp);
-extern int __dwarf_getaranges_internal (Dwarf *dbg, Dwarf_Aranges **aranges,
- size_t *naranges)
- __nonnull_attribute__ (2);
-extern int __dwarf_getarangeinfo_internal (Dwarf_Arange *arange,
- Dwarf_Addr *addrp,
- Dwarf_Word *lengthp,
- Dwarf_Off *offsetp);
-extern Dwarf_Arange *__dwarf_getarange_addr_internal (Dwarf_Aranges *aranges,
- Dwarf_Addr addr);
-extern Dwarf_Die *__dwarf_offdie_internal (Dwarf *dbg, Dwarf_Off offset,
- Dwarf_Die *result)
- __nonnull_attribute__ (3);
-extern int __dwarf_getsrclines_internal (Dwarf_Die *cudie, Dwarf_Lines **lines,
- size_t *nlines)
- __nonnull_attribute__ (2, 3);
-extern Dwarf_Attribute *__dwarf_attr_internal (Dwarf_Die *die,
- unsigned int search_name,
- Dwarf_Attribute *result)
- __nonnull_attribute__ (3);
-extern int __dwarf_formudata_internal (Dwarf_Attribute *attr,
- Dwarf_Word *return_uval)
- __nonnull_attribute__ (2);
-extern int __dwarf_formblock_internal (Dwarf_Attribute *attr,
- Dwarf_Block *return_block)
- __nonnull_attribute__ (2);
-extern const char *__dwarf_formstring_internal (Dwarf_Attribute *attrp);
-extern int __dwarf_formaddr_internal (Dwarf_Attribute *attr,
- Dwarf_Addr *return_addr)
- __nonnull_attribute__ (2);
-extern int __dwarf_tag_internal (Dwarf_Die *die);
-extern int __dwarf_formref_internal (Dwarf_Attribute *attr,
- Dwarf_Off *return_offset)
- __nonnull_attribute__ (2);
-extern int __dwarf_nextcu_internal (Dwarf *dwarf, Dwarf_Off off,
- Dwarf_Off *next_off, size_t *header_sizep,
- Dwarf_Off *abbrev_offsetp,
- uint8_t *address_sizep,
- uint8_t *offset_sizep)
- __nonnull_attribute__ (3);
-extern int __dwarf_child_internal (Dwarf_Die *die, Dwarf_Die *result)
- __nonnull_attribute__ (2);
-extern int __dwarf_siblingof_internal (Dwarf_Die *die, Dwarf_Die *result)
- __nonnull_attribute__ (2);
-extern Dwarf_Off __dwarf_dieoffset_internal (Dwarf_Die *die);
-extern int __dwarf_highpc_internal (Dwarf_Die *die, Dwarf_Addr *return_addr)
- __nonnull_attribute__ (2);
-extern int __dwarf_lowpc_internal (Dwarf_Die *die, Dwarf_Addr *return_addr)
- __nonnull_attribute__ (2);
-extern int __dwarf_formsdata_internal (Dwarf_Attribute *attr,
- Dwarf_Sword *return_uval)
- __nonnull_attribute__ (2);
+/* Aliases to avoid PLTs. */
+INTDECL (dwarf_attr)
+INTDECL (dwarf_attr_integrate)
+INTDECL (dwarf_begin_elf)
+INTDECL (dwarf_child)
+INTDECL (dwarf_dieoffset)
+INTDECL (dwarf_end)
+INTDECL (dwarf_errmsg)
+INTDECL (dwarf_formaddr)
+INTDECL (dwarf_formblock)
+INTDECL (dwarf_formref)
+INTDECL (dwarf_formref_die)
+INTDECL (dwarf_formsdata)
+INTDECL (dwarf_formstring)
+INTDECL (dwarf_formudata)
+INTDECL (dwarf_getarange_addr)
+INTDECL (dwarf_getarangeinfo)
+INTDECL (dwarf_getaranges)
+INTDECL (dwarf_getsrcfiles)
+INTDECL (dwarf_getsrclines)
+INTDECL (dwarf_hasattr)
+INTDECL (dwarf_haschildren)
+INTDECL (dwarf_haspc)
+INTDECL (dwarf_highpc)
+INTDECL (dwarf_lowpc)
+INTDECL (dwarf_nextcu)
+INTDECL (dwarf_offdie)
+INTDECL (dwarf_siblingof)
+INTDECL (dwarf_tag)
#endif /* libdwP.h */
diff --git a/elfutils/libdw/libdw_form.c b/elfutils/libdw/libdw_form.c
index 2543f5a2..95d47140 100644
--- a/elfutils/libdw/libdw_form.c
+++ b/elfutils/libdw/libdw_form.c
@@ -25,10 +25,10 @@
size_t
internal_function_def
__libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu, unsigned int form,
- unsigned char *valp)
+ const unsigned char *valp)
{
- unsigned char *saved;
- unsigned int u128;
+ const unsigned char *saved;
+ Dwarf_Word u128;
size_t result;
switch (form)
diff --git a/elfutils/libdw/libdw_visit_scopes.c b/elfutils/libdw/libdw_visit_scopes.c
new file mode 100644
index 00000000..06168fb1
--- /dev/null
+++ b/elfutils/libdw/libdw_visit_scopes.c
@@ -0,0 +1,104 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+enum die_class { ignore, match, match_inline, walk, imported };
+
+static enum die_class
+classify_die (Dwarf_Die *die)
+{
+ switch (INTUSE(dwarf_tag) (die))
+ {
+ /* DIEs with addresses we can try to match. */
+ case DW_TAG_compile_unit:
+ case DW_TAG_module:
+ case DW_TAG_lexical_block:
+ case DW_TAG_with_stmt:
+ case DW_TAG_catch_block:
+ case DW_TAG_try_block:
+ case DW_TAG_entry_point:
+ return match;
+ case DW_TAG_inlined_subroutine:
+ return match_inline;
+ case DW_TAG_subprogram:
+ /* This might be a concrete out-of-line instance of an inline, in
+ which case it is not guaranteed to be owned by the right scope and
+ we will search for its origin as for DW_TAG_inlined_subroutine. */
+ return (INTUSE(dwarf_hasattr) (die, DW_AT_abstract_origin)
+ ? match_inline : match);
+
+ /* DIEs without addresses that can own DIEs with addresses. */
+ case DW_TAG_namespace:
+ return walk;
+
+ /* Special indirection required. */
+ case DW_TAG_imported_unit:
+ return imported;
+
+ /* Other DIEs we have no reason to descend. */
+ default:
+ break;
+ }
+ return ignore;
+}
+
+int
+__libdw_visit_scopes (depth, root, visit, arg)
+ unsigned int depth;
+ Dwarf_Die *root;
+ int (*visit) (unsigned int depth, Dwarf_Die *die, void *arg);
+ void *arg;
+{
+ Dwarf_Die child;
+ if (INTUSE(dwarf_child) (root, &child) != 0)
+ return -1;
+
+ do
+ {
+ int result = (*visit) (depth, &child, arg);
+ if (result != DWARF_CB_OK)
+ return result;
+
+ switch (classify_die (&child))
+ {
+ case match:
+ case match_inline:
+ case walk:
+ if (INTUSE(dwarf_haschildren) (&child))
+ {
+ result = __libdw_visit_scopes (depth + 1, &child, visit, arg);
+ if (result != DWARF_CB_OK)
+ return result;
+ }
+ break;
+
+ case imported:
+ {
+ /* This is imports another compilation unit to appear
+ as part of this one, inside the current scope.
+ Recurse to searesulth the referenced unit, but without
+ recording it as an inner scoping level. */
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child, DW_AT_import,
+ &attr_mem);
+ if (INTUSE(dwarf_formref_die) (attr, &child) != NULL)
+ {
+ result = __libdw_visit_scopes (depth + 1, &child, visit, arg);
+ if (result != 0)
+ return result;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
+
+ return 0;
+}
diff --git a/elfutils/libdw/memory-access.c b/elfutils/libdw/memory-access.c
new file mode 100644
index 00000000..04899a81
--- /dev/null
+++ b/elfutils/libdw/memory-access.c
@@ -0,0 +1,35 @@
+/* Out of line functions for memory-access.h macros.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "libdwP.h"
+#include "memory-access.h"
+
+uint64_t
+internal_function_def
+__libdw_get_uleb128 (uint64_t acc, unsigned int i, const unsigned char **addrp)
+{
+ unsigned char __b;
+ get_uleb128_rest_return (acc, i, addrp);
+}
+
+int64_t
+internal_function_def
+__libdw_get_sleb128 (int64_t acc, unsigned int i, const unsigned char **addrp)
+{
+ unsigned char __b;
+ int64_t _v = acc;
+ get_sleb128_rest_return (acc, i, addrp);
+}
diff --git a/elfutils/libdw/memory-access.h b/elfutils/libdw/memory-access.h
index babe976f..8efd8993 100644
--- a/elfutils/libdw/memory-access.h
+++ b/elfutils/libdw/memory-access.h
@@ -1,5 +1,5 @@
/* Unaligned memory access functionality.
- Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
This program is Open Source software; you can redistribute it and/or
@@ -21,86 +21,88 @@
/* Number decoding macros. See 7.6 Variable Length Data. */
-#define get_uleb128(var, addr) \
+
+#define get_uleb128_step(var, addr, nth, break) \
+ __b = *(addr)++; \
+ var |= (uintmax_t) (__b & 0x7f) << (nth * 7); \
+ if (likely ((__b & 0x80) == 0)) \
+ break
+
+#define get_uleb128(var, addr) \
+ do { \
+ unsigned char __b; \
+ var = 0; \
+ get_uleb128_step (var, addr, 0, break); \
+ var = __libdw_get_uleb128 (var, 1, &(addr)); \
+ } while (0)
+
+#define get_uleb128_rest_return(var, i, addrp) \
do { \
- unsigned char __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- var = __b & 0x7f; \
- if (__b & 0x80) \
+ for (; i < 10; ++i) \
{ \
- __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- var |= (__b & 0x7f) << 7; \
- if (__b & 0x80) \
- { \
- __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- var |= (__b & 0x7f) << 14; \
- if (__b & 0x80) \
- { \
- __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- var |= (__b & 0x7f) << 21; \
- if (__b & 0x80) \
- /* Other implementation set VALUE to UINT_MAX in this \
- case. So we better do this as well. */ \
- var = UINT_MAX; \
- } \
- } \
+ get_uleb128_step (var, *addrp, i, return var); \
} \
+ /* Other implementations set VALUE to UINT_MAX in this \
+ case. So we better do this as well. */ \
+ return UINT64_MAX; \
} while (0)
-/* The signed case is a big more complicated. */
-#define get_sleb128(var, addr) \
- do { \
- unsigned char __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- int32_t __res = __b & 0x7f; \
- if ((__b & 0x80) == 0) \
+/* The signed case is similar, but we sign-extend the result. */
+
+#define get_sleb128_step(var, addr, nth, break) \
+ __b = *(addr)++; \
+ _v |= (uint64_t) (__b & 0x7f) << (nth * 7); \
+ if (likely ((__b & 0x80) == 0)) \
{ \
- if (__b & 0x40) \
- __res |= 0xffffff80; \
+ var = (_v << (64 - (nth * 7) - 7) >> (64 - (nth * 7) - 7)); \
+ break; \
} \
- else \
+ else do {} while (0)
+
+#define get_sleb128(var, addr) \
+ do { \
+ unsigned char __b; \
+ int64_t _v = 0; \
+ get_sleb128_step (var, addr, 0, break); \
+ var = __libdw_get_sleb128 (_v, 1, &(addr)); \
+ } while (0)
+
+#define get_sleb128_rest_return(var, i, addrp) \
+ do { \
+ for (; i < 9; ++i) \
{ \
- __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- __res |= (__b & 0x7f) << 7; \
- if ((__b & 0x80) == 0) \
- { \
- if (__b & 0x40) \
- __res |= 0xffffc000; \
- } \
- else \
- { \
- __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- __res |= (__b & 0x7f) << 14; \
- if ((__b & 0x80) == 0) \
- { \
- if (__b & 0x40) \
- __res |= 0xffe00000; \
- } \
- else \
- { \
- __b = *((const unsigned char *) addr); \
- addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \
- __res |= (__b & 0x7f) << 21; \
- if ((__b & 0x80) == 0) \
- { \
- if (__b & 0x40) \
- __res |= 0xf0000000; \
- } \
- else \
- /* Other implementation set VALUE to INT_MAX in this \
- case. So we better do this as well. */ \
- __res = INT_MAX; \
- } \
- } \
+ get_sleb128_step (var, *addrp, i, return var); \
} \
- var = __res; \
+ /* Other implementations set VALUE to INT_MAX in this \
+ case. So we better do this as well. */ \
+ return INT64_MAX; \
} while (0)
+#ifdef IS_LIBDW
+extern uint64_t __libdw_get_uleb128 (uint64_t acc, unsigned int i,
+ const unsigned char **addrp)
+ internal_function attribute_hidden;
+extern int64_t __libdw_get_sleb128 (int64_t acc, unsigned int i,
+ const unsigned char **addrp)
+ internal_function attribute_hidden;
+#else
+static uint64_t
+__attribute__ ((unused))
+__libdw_get_uleb128 (uint64_t acc, unsigned int i, const unsigned char **addrp)
+{
+ unsigned char __b;
+ get_uleb128_rest_return (acc, i, addrp);
+}
+static int64_t
+__attribute__ ((unused))
+__libdw_get_sleb128 (int64_t acc, unsigned int i, const unsigned char **addrp)
+{
+ unsigned char __b;
+ int64_t _v = acc;
+ get_sleb128_rest_return (acc, i, addrp);
+}
+#endif
+
/* We use simple memory access functions in case the hardware allows it.
The caller has to make sure we don't have alias problems. */
diff --git a/elfutils/libdwfl/ChangeLog b/elfutils/libdwfl/ChangeLog
new file mode 100644
index 00000000..139ab47b
--- /dev/null
+++ b/elfutils/libdwfl/ChangeLog
@@ -0,0 +1,189 @@
+2005-08-24 Roland McGrath <roland@redhat.com>
+
+ * argp-std.c [_MUDFLAP] (__libdwfl_argp_mudflap_options): New function,
+ magic initializer to set -heur-stack-bound option.
+
+2005-08-22 Roland McGrath <roland@redhat.com>
+
+ * dwfl_validate_address.c: New file.
+ * Makefile.am (libdwfl_a_SOURCES): Add it.
+ * libdwfl.h: Declare dwfl_validate_address.
+
+ * derelocate.c (dwfl_module_relocate_address): Add INTDEF.
+ * libdwflP.h: Add INTDECL.
+
+ * dwfl_module_getdwarf.c (find_symtab): Use elf_getdata instead of
+ elf_rawdata for symbol-related sections.
+
+ * offline.c (dwfl_report_offline): Move offline_next_address outside
+ module's range, in case it's an ET_EXEC using fixed segment locations.
+ * libdwfl.h: Update comment.
+
+ * dwfl_report_elf.c (dwfl_report_elf): Align BASE to first segment's
+ required alignment.
+
+2005-08-20 Roland McGrath <roland@redhat.com>
+
+ * linux-kernel-modules.c (report_kernel): Take new argument PREDICATE,
+ function to choose whether to report.
+ (dwfl_linux_kernel_report_offline): Likewise.
+ * libdwfl.h: Update decl.
+ * argp-std.c (parse_opt): Update caller.
+
+ * dwfl_getsrclines.c: New file.
+ * dwfl_onesrcline.c: New file.
+ * Makefile.am (libdwfl_a_SOURCES): Add them.
+ * libdwfl.h: Declare dwfl_getsrclines, dwfl_onesrcline.
+
+ * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't leak
+ MODULESDIR[0]. Call fts_close on failure.
+
+ * dwfl_module_getdwarf.c (load_dw): Take dwfl_file * instead of Elf *.
+ Close ET_REL file descriptors after relocation.
+ (find_dw): Update caller.
+ * offline.c (dwfl_report_offline): Get the file into memory and close
+ the file descriptor.
+
+ * dwfl_module_getdwarf.c (find_debuginfo): Do nothing when
+ MOD->debug.elf is already set.
+
+ * find-debuginfo.c (try_open): Use TEMP_FAILURE_RETRY.
+ (dwfl_standard_find_debuginfo): Fail on errors not ENOENT or ENOTDIR.
+
+ * argp-std.c (options, parse_opt): Grok -K/--offline-kernel, use
+ dwfl_linux_kernel_report_offline with offline_callbacks.
+
+ * linux-kernel-modules.c (report_kernel): New function, broken out of
+ ...
+ (dwfl_linux_kernel_report_kernel): ... here. Use it.
+ (dwfl_linux_kernel_report_offline): New function.
+ * libdwfl.h: Declare it.
+ * libdwflP.h: Add INTDECL.
+
+2005-08-19 Roland McGrath <roland@redhat.com>
+
+ Use standard debuginfo search path to look for vmlinux.
+ * find-debuginfo.c (dwfl_standard_find_debuginfo): Don't check CRC if
+ passed zero.
+ * linux-kernel-modules.c (try_kernel_name): New function, broken out
+ of ...
+ (dwfl_linux_kernel_report_kernel): ... here. Use it.
+
+ * argp-std.c (offline_callbacks): New variable.
+ (parse_opt): Use it for -e. Allow multiple -e options.
+
+ * offline.c: New file.
+ * Makefile.am (libdwfl_a_SOURCES): Add it.
+ * libdwfl.h: Declare dwfl_offline_section_address, dwfl_report_offline.
+ * libdwflP.h: Add INTDECLs.
+ (OFFLINE_REDZONE): New macro.
+ (struct Dwfl): New member `offline_next_address'.
+ * dwfl_begin.c (dwfl_begin): Initialize it.
+ * dwfl_module.c (dwfl_report_begin): Likewise.
+
+ * dwfl_report_elf.c (dwfl_report_elf): Accept all types. When ET_REL,
+ do a nominal absolute section layout starting at BASE.
+ * libdwfl.h: Update comment.
+
+2005-08-18 Roland McGrath <roland@redhat.com>
+
+ * dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Do
+ dwfl_module_getdwarf if necessary.
+
+ * dwfl_report_elf.c (dwfl_report_elf): Permit ET_REL with BASE==0.
+ * libdwfl.h: Update comment.
+
+ * derelocate.c: New file.
+ * Makefile.am (libdwfl_a_SOURCES): Add it.
+
+ * libdwflP.h (struct Dwfl_Module): isrel -> e_type.
+ * dwfl_report_elf.c (dwfl_report_elf): Initialize it.
+ * dwfl_module_getdwarf.c (open_elf): Update initialization.
+ (load_dw, dwfl_module_addrname): Update uses.
+ * relocate.c (__libdwfl_relocate): Likewise.
+
+2005-08-04 Roland McGrath <roland@redhat.com>
+
+ * libdwfl.h (Dwfl_Callbacks.section_address): Take additional
+ arguments SHNDX, SHDR.
+ (dwfl_linux_kernel_module_section_address): Update prototype.
+ * relocate.c (__libdwfl_relocate_value): Update caller.
+ * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address):
+ Take the new arguments.
+
+2005-08-10 Roland McGrath <roland@redhat.com>
+
+ * relocate.c (__libdwfl_relocate): Take argument DEBUGFILE,
+ use it instead of MOD->debug.file.
+ * libdwflP.h: Update decl.
+ * dwfl_module_getdwarf.c (load_dw): Update caller.
+ Fixes bug #165598.
+
+2005-08-09 Roland McGrath <roland@redhat.com>
+
+ * libdwflP.h: Include ../libdw/libdwP.h for its INTDECLs.
+ * cu.c: Use INTUSE on dwarf_* calls.
+ * dwfl_error.c: Likewise.
+ * dwfl_module.c: Likewise.
+ * dwfl_module_getdwarf.c: Likewise.
+ * dwfl_module_getsrc_file.c: Likewise.
+ * lines.c: Likewise.
+
+2005-08-07 Roland McGrath <roland@redhat.com>
+
+ * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): When module
+ names contain '_' or '-', look for files named either "foo-bar.ko"
+ or "foo_bar.ko".
+
+2005-07-29 Roland McGrath <roland@redhat.com>
+
+ * loc2c.c: File removed.
+ * loc2c.h: File removed.
+ * loc2c-runtime.h: File removed.
+ * test2.c: File removed.
+ * Makefile.am (EXTRA_DIST): Variable removed.
+ (noinst_HEADERS): Remove loc2c.h from here.
+
+2005-07-28 Ulrich Drepper <drepper@redhat.com>
+
+ * libdwfl.h: Add a few missing extern for function prototypes.
+
+ * libdwfl_crc32.c: New file.
+ * libdwfl_crc32_file.c: New file.
+ * libdwflP.h: Declare the new functions.
+ * Makefile.am (libdwfl_a_SOURCES): Add libdwfl_crc32.c and
+ libdwfl_crc32_file.c.
+ * libdwfl/find-debuginfo.c (check_crc): Use __libdwfl_crc32_file
+ instead of crc32_file.
+
+2005-07-28 Roland McGrath <roland@redhat.com>
+
+ * ptest.c: Moved to ../tests/dwflmodtest.c.
+
+ * Makefile.am (noinst_PROGRAMS): Variable removed.
+ (libdwfl_so_SOURCES, libdwfl_LIBS, libdwfl_so_LDADD): Likewise.
+ (EXTRA_DIST, ptest_LDADD, test2_LDADD): Likewise.
+ (libdwfl): Don't use libdwfl.so any more.
+ (libdwfl.so, install, uninstall): Targets removed.
+ (test2_SOURCES): Define EXTRA_DIST instead of this.
+ * libdwfl.map: File removed.
+
+ * libdwfl.h: Use "" for libdw.h #include.
+
+2005-07-27 Roland McGrath <roland@redhat.com>
+
+ * libdwfl.map: Add dwfl_getmodules.
+
+2005-07-23 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am: Fix rules to allow building with mudflap.
+
+2005-07-21 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am (noinst_HEADERS): Add loc2c.c.
+
+ * test2.c (main): Check sscanf result to quiet warning.
+
+2005-07-20 Roland McGrath <roland@redhat.com>
+
+ * libdwfl-branch merged, creating this direcotry.
diff --git a/elfutils/libdwfl/Makefile.am b/elfutils/libdwfl/Makefile.am
new file mode 100644
index 00000000..a0735ff0
--- /dev/null
+++ b/elfutils/libdwfl/Makefile.am
@@ -0,0 +1,84 @@
+## Makefile.am for libdwfl library subdirectory in elfutils.
+##
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2005 Red Hat, Inc.
+##
+## This program is Open Source software; you can redistribute it and/or
+## modify it under the terms of the Open Software License version 1.0 as
+## published by the Open Source Initiative.
+##
+## You should have received a copy of the Open Software License along
+## with this program; if not, you may obtain a copy of the Open Software
+## License version 1.0 from http://www.opensource.org/licenses/osl.php or
+## by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+## 3001 King Ranch Road, Ukiah, CA 95482.
+##
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H
+if MUDFLAP
+AM_CFLAGS = -fmudflap
+else
+AM_CFLAGS =
+endif
+AM_CFLAGS += -Wall -Werror -Wshadow -Wunused -Wformat=2 -Wextra -std=gnu99
+INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+ -I$(srcdir)/../libdw -I.. -I$(srcdir)/../lib
+VERSION = 1
+
+noinst_LIBRARIES = libdwfl.a
+if !MUDFLAP
+noinst_LIBRARIES += libdwfl_pic.a
+endif
+
+euincludedir = ${includedir}/elfutils
+euinclude_HEADERS = libdwfl.h
+
+libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c \
+ dwfl_module.c dwfl_report_elf.c relocate.c \
+ derelocate.c offline.c \
+ dwfl_module_info.c dwfl_getmodules.c \
+ dwfl_module_getdwarf.c dwfl_getdwarf.c \
+ dwfl_validate_address.c \
+ argp-std.c find-debuginfo.c \
+ linux-kernel-modules.c linux-proc-maps.c \
+ dwfl_addrmodule.c dwfl_addrdwarf.c \
+ cu.c dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
+ dwfl_module_addrdie.c dwfl_addrdie.c \
+ lines.c dwfl_lineinfo.c dwfl_linemodule.c \
+ dwfl_getsrclines.c dwfl_onesrcline.c \
+ dwfl_module_getsrc.c dwfl_getsrc.c \
+ dwfl_module_getsrc_file.c \
+ libdwfl_crc32.c libdwfl_crc32_file.c \
+ elf-from-memory.c
+
+
+if MUDFLAP
+libdwfl = libdwfl.a $(libdw) $(libebl) $(libelf) $(libeu)
+libdw = ../libdw/libdw.a
+libelf = ../libelf/libelf.a
+libmudflap = -lmudflap
+else
+libdwfl = $(libdw)
+libdw = ../libdw/libdw.so
+libelf = ../libelf/libelf.so
+endif
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+
+
+if !MUDFLAP
+libdwfl_pic_a_SOURCES =
+am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os)
+
+%.os: %.c %.o
+ if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
+ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
+ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
+ rm -f "$(DEPDIR)/$*.Tpo"; \
+ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+ fi
+endif
+
+noinst_HEADERS = libdwflP.h
+
+CLEANFILES = $(am_libdwfl_pic_a_OBJECTS)
diff --git a/elfutils/libdwfl/Makefile.in b/elfutils/libdwfl/Makefile.in
new file mode 100644
index 00000000..ae41d2b1
--- /dev/null
+++ b/elfutils/libdwfl/Makefile.in
@@ -0,0 +1,542 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@MUDFLAP_FALSE@am__append_1 = libdwfl_pic.a
+@MUDFLAP_TRUE@am_libdwfl_pic_a_OBJECTS =
+subdir = libdwfl
+DIST_COMMON = $(euinclude_HEADERS) $(noinst_HEADERS) \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libdwfl_a_AR = $(AR) $(ARFLAGS)
+libdwfl_a_LIBADD =
+am_libdwfl_a_OBJECTS = dwfl_begin.$(OBJEXT) dwfl_end.$(OBJEXT) \
+ dwfl_error.$(OBJEXT) dwfl_module.$(OBJEXT) \
+ dwfl_report_elf.$(OBJEXT) relocate.$(OBJEXT) \
+ derelocate.$(OBJEXT) offline.$(OBJEXT) \
+ dwfl_module_info.$(OBJEXT) dwfl_getmodules.$(OBJEXT) \
+ dwfl_module_getdwarf.$(OBJEXT) dwfl_getdwarf.$(OBJEXT) \
+ dwfl_validate_address.$(OBJEXT) argp-std.$(OBJEXT) \
+ find-debuginfo.$(OBJEXT) linux-kernel-modules.$(OBJEXT) \
+ linux-proc-maps.$(OBJEXT) dwfl_addrmodule.$(OBJEXT) \
+ dwfl_addrdwarf.$(OBJEXT) cu.$(OBJEXT) \
+ dwfl_module_nextcu.$(OBJEXT) dwfl_nextcu.$(OBJEXT) \
+ dwfl_cumodule.$(OBJEXT) dwfl_module_addrdie.$(OBJEXT) \
+ dwfl_addrdie.$(OBJEXT) lines.$(OBJEXT) dwfl_lineinfo.$(OBJEXT) \
+ dwfl_linemodule.$(OBJEXT) dwfl_getsrclines.$(OBJEXT) \
+ dwfl_onesrcline.$(OBJEXT) dwfl_module_getsrc.$(OBJEXT) \
+ dwfl_getsrc.$(OBJEXT) dwfl_module_getsrc_file.$(OBJEXT) \
+ libdwfl_crc32.$(OBJEXT) libdwfl_crc32_file.$(OBJEXT) \
+ elf-from-memory.$(OBJEXT)
+libdwfl_a_OBJECTS = $(am_libdwfl_a_OBJECTS)
+libdwfl_pic_a_AR = $(AR) $(ARFLAGS)
+libdwfl_pic_a_LIBADD =
+libdwfl_pic_a_OBJECTS = $(am_libdwfl_pic_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libdwfl_a_SOURCES) $(libdwfl_pic_a_SOURCES)
+DIST_SOURCES = $(libdwfl_a_SOURCES) $(libdwfl_pic_a_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(euincludedir)"
+euincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(euinclude_HEADERS) $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EXEEXT = @EXEEXT@
+GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LOCALEDIR = @LOCALEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+MUDFLAP_FALSE = @MUDFLAP_FALSE@
+MUDFLAP_TRUE = @MUDFLAP_TRUE@
+NATIVE_LD_FALSE = @NATIVE_LD_FALSE@
+NATIVE_LD_TRUE = @NATIVE_LD_TRUE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = 1
+XGETTEXT = @XGETTEXT@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+base_cpu = @base_cpu@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Werror -Wshadow -Wunused -Wformat=2 \
+@MUDFLAP_FALSE@ -Wextra -std=gnu99
+@MUDFLAP_TRUE@AM_CFLAGS = -fmudflap -Wall -Werror -Wshadow -Wunused \
+@MUDFLAP_TRUE@ -Wformat=2 -Wextra -std=gnu99
+INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+ -I$(srcdir)/../libdw -I.. -I$(srcdir)/../lib
+
+noinst_LIBRARIES = libdwfl.a $(am__append_1)
+euincludedir = ${includedir}/elfutils
+euinclude_HEADERS = libdwfl.h
+libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c \
+ dwfl_module.c dwfl_report_elf.c relocate.c \
+ derelocate.c offline.c \
+ dwfl_module_info.c dwfl_getmodules.c \
+ dwfl_module_getdwarf.c dwfl_getdwarf.c \
+ dwfl_validate_address.c \
+ argp-std.c find-debuginfo.c \
+ linux-kernel-modules.c linux-proc-maps.c \
+ dwfl_addrmodule.c dwfl_addrdwarf.c \
+ cu.c dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
+ dwfl_module_addrdie.c dwfl_addrdie.c \
+ lines.c dwfl_lineinfo.c dwfl_linemodule.c \
+ dwfl_getsrclines.c dwfl_onesrcline.c \
+ dwfl_module_getsrc.c dwfl_getsrc.c \
+ dwfl_module_getsrc_file.c \
+ libdwfl_crc32.c libdwfl_crc32_file.c \
+ elf-from-memory.c
+
+@MUDFLAP_FALSE@libdwfl = $(libdw)
+@MUDFLAP_TRUE@libdwfl = libdwfl.a $(libdw) $(libebl) $(libelf) $(libeu)
+@MUDFLAP_FALSE@libdw = ../libdw/libdw.so
+@MUDFLAP_TRUE@libdw = ../libdw/libdw.a
+@MUDFLAP_FALSE@libelf = ../libelf/libelf.so
+@MUDFLAP_TRUE@libelf = ../libelf/libelf.a
+@MUDFLAP_TRUE@libmudflap = -lmudflap
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+@MUDFLAP_FALSE@libdwfl_pic_a_SOURCES =
+@MUDFLAP_FALSE@am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os)
+noinst_HEADERS = libdwflP.h
+CLEANFILES = $(am_libdwfl_pic_a_OBJECTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdwfl/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnits libdwfl/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libdwfl.a: $(libdwfl_a_OBJECTS) $(libdwfl_a_DEPENDENCIES)
+ -rm -f libdwfl.a
+ $(libdwfl_a_AR) libdwfl.a $(libdwfl_a_OBJECTS) $(libdwfl_a_LIBADD)
+ $(RANLIB) libdwfl.a
+libdwfl_pic.a: $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_DEPENDENCIES)
+ -rm -f libdwfl_pic.a
+ $(libdwfl_pic_a_AR) libdwfl_pic.a $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_LIBADD)
+ $(RANLIB) libdwfl_pic.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-std.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/derelocate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrdie.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrdwarf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrmodule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_begin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_cumodule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_end.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_error.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getdwarf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getmodules.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getsrc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getsrclines.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_lineinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_linemodule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_addrdie.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getdwarf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsrc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsrc_file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_info.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_nextcu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_nextcu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_onesrcline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_report_elf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_validate_address.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-from-memory.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find-debuginfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwfl_crc32.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwfl_crc32_file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lines.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-kernel-modules.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-proc-maps.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/offline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relocate.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+install-euincludeHEADERS: $(euinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(euincludedir)" || $(mkdir_p) "$(DESTDIR)$(euincludedir)"
+ @list='$(euinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(euincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(euincludedir)/$$f'"; \
+ $(euincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(euincludedir)/$$f"; \
+ done
+
+uninstall-euincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(euinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(euincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(euincludedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(euincludedir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-euincludeHEADERS
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-euincludeHEADERS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-noinstLIBRARIES ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-euincludeHEADERS install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-euincludeHEADERS \
+ uninstall-info-am
+
+
+@MUDFLAP_FALSE@%.os: %.c %.o
+@MUDFLAP_FALSE@ if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
+@MUDFLAP_FALSE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
+@MUDFLAP_FALSE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
+@MUDFLAP_FALSE@ rm -f "$(DEPDIR)/$*.Tpo"; \
+@MUDFLAP_FALSE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@MUDFLAP_FALSE@ fi
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/elfutils/libdwfl/argp-std.c b/elfutils/libdwfl/argp-std.c
new file mode 100644
index 00000000..4a6e1607
--- /dev/null
+++ b/elfutils/libdwfl/argp-std.c
@@ -0,0 +1,210 @@
+/* Standard argp argument parsers for tools using libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include <argp.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <libintl.h>
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+#define OPT_DEBUGINFO 0x100
+
+static const struct argp_option options[] =
+{
+ { NULL, 0, NULL, 0, N_("Input Selection:"), 0 },
+ { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 },
+ { "pid", 'p', "PID", 0,
+ N_("Find addresses in files mapped into process PID"), 0 },
+ { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 },
+ { "offline-kernel", 'K', "RELEASE", OPTION_ARG_OPTIONAL,
+ N_("Kernel with all modules"), 0 },
+ { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0,
+ N_("Search path for separate debuginfo files"), 0 },
+ { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+static char *debuginfo_path;
+
+static const Dwfl_Callbacks offline_callbacks =
+ {
+ .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+ .debuginfo_path = &debuginfo_path,
+
+ .section_address = INTUSE(dwfl_offline_section_address),
+ };
+
+static const Dwfl_Callbacks proc_callbacks =
+ {
+ .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+ .debuginfo_path = &debuginfo_path,
+
+ .find_elf = INTUSE(dwfl_linux_proc_find_elf),
+ };
+
+static const Dwfl_Callbacks kernel_callbacks =
+ {
+ .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+ .debuginfo_path = &debuginfo_path,
+
+ .find_elf = INTUSE(dwfl_linux_kernel_find_elf),
+ .section_address = INTUSE(dwfl_linux_kernel_module_section_address),
+ };
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ inline void failure (int errnum, const char *msg)
+ {
+ if (errnum == -1)
+ argp_failure (state, EXIT_FAILURE, 0, "%s: %s",
+ msg, INTUSE(dwfl_errmsg) (-1));
+ else
+ argp_failure (state, EXIT_FAILURE, errnum, "%s", msg);
+ }
+ inline error_t fail (int errnum, const char *msg)
+ {
+ failure (errnum, msg);
+ return errnum == -1 ? EIO : errnum;
+ }
+
+ switch (key)
+ {
+ case OPT_DEBUGINFO:
+ debuginfo_path = arg;
+ break;
+
+ case 'e':
+ {
+ Dwfl *dwfl = state->hook;
+ if (dwfl == NULL)
+ {
+ dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+ if (dwfl == NULL)
+ return fail (-1, arg);
+ state->hook = dwfl;
+ }
+ if (dwfl->callbacks == &offline_callbacks)
+ {
+ if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
+ return fail (-1, arg);
+ state->hook = dwfl;
+ }
+ else
+ {
+ toomany:
+ argp_error (state,
+ "%s", _("only one of -e, -p, -k, or -K allowed"));
+ return EINVAL;
+ }
+ }
+ break;
+
+ case 'p':
+ if (state->hook == NULL)
+ {
+ Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
+ int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
+ if (result != 0)
+ return fail (result, arg);
+ state->hook = dwfl;
+ }
+ else
+ goto toomany;
+ break;
+
+ case 'k':
+ if (state->hook == NULL)
+ {
+ Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
+ int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
+ if (result != 0)
+ return fail (result, _("cannot load kernel symbols"));
+ result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
+ if (result != 0)
+ /* Non-fatal to have no modules since we do have the kernel. */
+ failure (result, _("cannot find kernel modules"));
+ state->hook = dwfl;
+ }
+ else
+ goto toomany;
+ break;
+
+ case 'K':
+ if (state->hook == NULL)
+ {
+ Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+ int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
+ NULL);
+ if (result != 0)
+ return fail (result, _("cannot find kernel or modules"));
+ state->hook = dwfl;
+ }
+ else
+ goto toomany;
+ break;
+
+ case ARGP_KEY_SUCCESS:
+ {
+ Dwfl *dwfl = state->hook;
+
+ if (dwfl == NULL)
+ {
+ /* Default if no -e, -p, or -k, is "-e a.out". */
+ arg = "a.out";
+ dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+ if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
+ return fail (-1, arg);
+ state->hook = dwfl;
+ }
+
+ /* One of the three flavors has done dwfl_begin and some reporting
+ if we got here. Tie up the Dwfl and return it to the caller of
+ argp_parse. */
+
+ int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL);
+ assert (result == 0);
+
+ *(Dwfl **) state->input = dwfl;
+ }
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static const struct argp libdwfl_argp =
+ { .options = options, .parser = parse_opt };
+
+const struct argp *
+dwfl_standard_argp (void)
+{
+ return &libdwfl_argp;
+}
+
+#ifdef _MUDFLAP
+/* In the absence of a mudflap wrapper for argp_parse, or a libc compiled
+ with -fmudflap, we'll see spurious errors for using the struct argp_state
+ on argp_parse's stack. */
+
+void __attribute__ ((constructor))
+__libdwfl_argp_mudflap_options (void)
+{
+ __mf_set_options ("-heur-stack-bound");
+}
+#endif
diff --git a/elfutils/libdwfl/cu.c b/elfutils/libdwfl/cu.c
new file mode 100644
index 00000000..cf7e3887
--- /dev/null
+++ b/elfutils/libdwfl/cu.c
@@ -0,0 +1,275 @@
+/* Keeping track of DWARF compilation units in libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+#include "../libdw/memory-access.h"
+#include <search.h>
+
+
+static inline Dwarf_Arange *
+dwar (Dwfl_Module *mod, unsigned int idx)
+{
+ return &mod->dw->aranges->info[mod->aranges[idx].arange];
+}
+
+
+static Dwfl_Error
+addrarange (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_arange **arange)
+{
+ if (mod->aranges == NULL)
+ {
+ Dwarf_Aranges *dwaranges;
+ if (INTUSE(dwarf_getaranges) (mod->dw, &dwaranges, NULL) != 0)
+ return DWFL_E_LIBDW;
+
+ struct dwfl_arange *aranges = malloc (dwaranges->naranges
+ * sizeof *aranges);
+ if (unlikely (aranges == NULL))
+ return DWFL_E_NOMEM;
+
+ /* libdw has sorted its list by address, which is how we want it.
+ But the sorted list is full of not-quite-contiguous runs pointing
+ to the same CU. We don't care about the little gaps inside the
+ module, we'll consider them part of the surrounding CU anyway.
+ Collect our own array with just one record for each run of ranges
+ pointing to one CU. */
+
+ size_t naranges = 0;
+ Dwarf_Off lastcu = 0;
+ for (size_t i = 0; i < dwaranges->naranges; ++i)
+ if (i == 0 || dwaranges->info[i].offset != lastcu)
+ {
+ aranges[naranges].arange = i;
+ aranges[naranges].cu = NULL;
+ ++naranges;
+ lastcu = dwaranges->info[i].offset;
+ }
+
+ /* Store the final array, which is probably much smaller than before. */
+ mod->naranges = naranges;
+ mod->aranges = (realloc (aranges, naranges * sizeof aranges[0])
+ ?: aranges);
+ mod->lazycu += naranges;
+ }
+
+ /* The address must be inside the module to begin with. */
+ addr -= mod->debug.bias;
+
+ /* The ranges are sorted by address, so we can use binary search. */
+ size_t l = 0, u = mod->naranges;
+ while (l < u)
+ {
+ size_t idx = (l + u) / 2;
+ Dwarf_Addr start = dwar (mod, idx)->addr;
+ if (addr < start)
+ {
+ u = idx;
+ continue;
+ }
+ else if (addr > start)
+ {
+ if (idx + 1 < mod->naranges)
+ {
+ if (addr >= dwar (mod, idx + 1)->addr)
+ {
+ l = idx + 1;
+ continue;
+ }
+ }
+ else
+ {
+ /* It might be in the last range. */
+ const Dwarf_Arange *last
+ = &mod->dw->aranges->info[mod->dw->aranges->naranges - 1];
+ if (addr > last->addr + last->length)
+ break;
+ }
+ }
+
+ *arange = &mod->aranges[idx];
+ return DWFL_E_NOERROR;
+ }
+
+ return DWFL_E_ADDR_OUTOFRANGE;
+}
+
+
+static void
+nofree (void *arg)
+{
+ struct dwfl_cu *cu = arg;
+ if (cu == (void *) -1l)
+ return;
+
+ assert (cu->mod->lazycu == 0);
+}
+
+/* One reason fewer to keep the lazy lookup table for CUs. */
+static inline void
+less_lazy (Dwfl_Module *mod)
+{
+ if (--mod->lazycu > 0)
+ return;
+
+ /* We know about all the CUs now, we don't need this table. */
+ tdestroy (mod->lazy_cu_root, nofree);
+ mod->lazy_cu_root = NULL;
+}
+
+static inline Dwarf_Off
+cudie_offset (const struct dwfl_cu *cu)
+{
+ return cu->die.cu->start + 3 * cu->die.cu->offset_size - 4 + 3;
+}
+
+static int
+compare_cukey (const void *a, const void *b)
+{
+ return cudie_offset (a) - cudie_offset (b);
+}
+
+/* Intern the CU if necessary. */
+static Dwfl_Error
+intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result)
+{
+ struct Dwarf_CU dwkey;
+ struct dwfl_cu key;
+ key.die.cu = &dwkey;
+ dwkey.offset_size = 0;
+ dwkey.start = cuoff - (3 * 0 - 4 + 3);
+ struct dwfl_cu **found = tsearch (&key, &mod->lazy_cu_root, &compare_cukey);
+ if (unlikely (found == NULL))
+ return DWFL_E_NOMEM;
+
+ if (*found == &key || *found == NULL)
+ {
+ if (unlikely (cuoff + 4 >= mod->dw->sectiondata[IDX_debug_info]->d_size))
+ {
+ /* This is the EOF marker. Now we have interned all the CUs.
+ One increment in MOD->lazycu counts not having hit EOF yet. */
+ *found = (void *) -1l;
+ less_lazy (mod);
+ }
+ else
+ {
+ /* This is a new entry, meaning we haven't looked at this CU. */
+
+ *found = NULL;
+
+ struct dwfl_cu *cu = malloc (sizeof *cu);
+ if (unlikely (cu == NULL))
+ return DWFL_E_NOMEM;
+
+ cu->mod = mod;
+ cu->next = NULL;
+ cu->lines = NULL;
+
+ /* XXX use non-searching lookup */
+ Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cu->die);
+ if (die == NULL)
+ return DWFL_E_LIBDW;
+ assert (die == &cu->die);
+
+ struct dwfl_cu **newvec = realloc (mod->cu, ((mod->ncu + 1)
+ * sizeof (mod->cu[0])));
+ if (newvec == NULL)
+ {
+ free (cu);
+ return DWFL_E_NOMEM;
+ }
+ mod->cu = newvec;
+
+ mod->cu[mod->ncu++] = cu;
+ if (cu->die.cu->start == 0)
+ mod->first_cu = cu;
+
+ *found = cu;
+ }
+ }
+
+ *result = *found;
+ return DWFL_E_NOERROR;
+}
+
+
+/* Traverse all the CUs in the module. */
+
+Dwfl_Error
+internal_function_def
+__libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
+ struct dwfl_cu **cu)
+{
+ Dwarf_Off cuoff;
+ struct dwfl_cu **nextp;
+
+ if (lastcu == NULL)
+ {
+ /* Start the traversal. */
+ cuoff = 0;
+ nextp = &mod->first_cu;
+ }
+ else
+ {
+ /* Continue following LASTCU. */
+ cuoff = lastcu->die.cu->end;
+ nextp = &lastcu->next;
+ }
+
+ if (*nextp == NULL)
+ {
+ size_t cuhdrsz;
+ Dwarf_Off nextoff;
+ if (INTUSE(dwarf_nextcu) (mod->dw, cuoff, &nextoff, &cuhdrsz,
+ NULL, NULL, NULL) != 0)
+ return DWFL_E_LIBDW;
+
+ Dwfl_Error result = intern_cu (mod, cuoff + cuhdrsz, nextp);
+ if (result != DWFL_E_NOERROR)
+ return result;
+
+ if ((*nextp)->next == NULL && nextoff == (Dwarf_Off) -1l)
+ (*nextp)->next = (void *) -1l;
+ }
+
+ *cu = *nextp == (void *) -1l ? NULL : *nextp;
+ return DWFL_E_NOERROR;
+}
+
+
+/* Intern the CU arange points to, if necessary. */
+
+static Dwfl_Error
+arangecu (Dwfl_Module *mod, struct dwfl_arange *arange, struct dwfl_cu **cu)
+{
+ if (arange->cu == NULL)
+ {
+ const Dwarf_Arange *dwarange = &mod->dw->aranges->info[arange->arange];
+ Dwfl_Error result = intern_cu (mod, dwarange->offset, &arange->cu);
+ if (result != DWFL_E_NOERROR)
+ return result;
+ assert (arange->cu != NULL && arange->cu != (void *) -1l);
+ less_lazy (mod); /* Each arange with null ->cu counts once. */
+ }
+
+ *cu = arange->cu;
+ return DWFL_E_NOERROR;
+}
+
+Dwfl_Error
+internal_function_def
+__libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_cu **cu)
+{
+ struct dwfl_arange *arange;
+ return addrarange (mod, addr, &arange) ?: arangecu (mod, arange, cu);
+}
diff --git a/elfutils/libdwfl/derelocate.c b/elfutils/libdwfl/derelocate.c
new file mode 100644
index 00000000..b2b16f49
--- /dev/null
+++ b/elfutils/libdwfl/derelocate.c
@@ -0,0 +1,231 @@
+/* Recover relocatibility for addresses computed from debug information.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+struct dwfl_relocation
+{
+ size_t count;
+ struct
+ {
+ Elf_Scn *scn;
+ const char *name;
+ GElf_Addr start, end;
+ } refs[0];
+};
+
+
+struct secref
+{
+ struct secref *next;
+ Elf_Scn *scn;
+ const char *name;
+ GElf_Addr start, end;
+};
+
+static int
+compare_secrefs (const void *a, const void *b)
+{
+ struct secref *const *p1 = a;
+ struct secref *const *p2 = b;
+
+ return (*p1)->start - (*p2)->start;
+}
+
+static int
+cache_sections (Dwfl_Module *mod)
+{
+ size_t symshstrndx;
+ if (elf_getshstrndx (mod->symfile->elf, &symshstrndx) < 0)
+ {
+ __libdwfl_seterrno (DWFL_E_LIBELF);
+ return -1;
+ }
+
+ struct secref *refs = NULL;
+ size_t nrefs = 0;
+
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (mod->symfile->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr == NULL)
+ return -1;
+
+ if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr != 0)
+ {
+ const char *name = elf_strptr (mod->symfile->elf, symshstrndx,
+ shdr->sh_name);
+ if (name == NULL)
+ return -1;
+
+ struct secref *newref = alloca (sizeof *newref);
+ newref->scn = scn;
+ newref->name = name;
+ newref->start = shdr->sh_addr;
+ newref->end = shdr->sh_addr + shdr->sh_size;
+ newref->next = refs;
+ refs = newref;
+ ++nrefs;
+ }
+ }
+
+ mod->reloc_info = malloc (offsetof (struct dwfl_relocation, refs[nrefs]));
+ if (mod->reloc_info == NULL)
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return -1;
+ }
+
+ struct secref *sortrefs[nrefs];
+ for (size_t i = nrefs; i-- > 0; refs = refs->next)
+ sortrefs[i] = refs;
+ assert (refs == NULL);
+
+ qsort (sortrefs, nrefs, sizeof sortrefs[0], &compare_secrefs);
+
+ mod->reloc_info->count = nrefs;
+ for (size_t i = 0; i < nrefs; ++i)
+ {
+ mod->reloc_info->refs[i].name = sortrefs[i]->name;
+ mod->reloc_info->refs[i].scn = sortrefs[i]->scn;
+ mod->reloc_info->refs[i].start = sortrefs[i]->start;
+ mod->reloc_info->refs[i].end = sortrefs[i]->end;
+ }
+
+ return nrefs;
+}
+
+
+int
+dwfl_module_relocations (Dwfl_Module *mod)
+{
+ if (mod == NULL)
+ return -1;
+
+ if (mod->reloc_info != NULL)
+ return mod->reloc_info->count;
+
+ if (mod->dw == NULL)
+ {
+ Dwarf_Addr bias;
+ if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
+ return -1;
+ }
+
+ switch (mod->e_type)
+ {
+ case ET_REL:
+ return cache_sections (mod);
+
+ case ET_DYN:
+ return 1;
+
+ case ET_EXEC:
+ assert (mod->debug.bias == 0);
+ break;
+ }
+
+ return 0;
+}
+
+const char *
+dwfl_module_relocation_info (Dwfl_Module *mod, unsigned int idx,
+ Elf32_Word *shndxp)
+{
+ if (mod == NULL)
+ return NULL;
+
+ switch (mod->e_type)
+ {
+ case ET_REL:
+ break;
+
+ case ET_DYN:
+ if (idx != 0)
+ return NULL;
+ if (shndxp)
+ *shndxp = SHN_ABS;
+ return "";
+
+ default:
+ return NULL;
+ }
+
+ if (unlikely (mod->reloc_info == NULL) && cache_sections (mod) < 0)
+ return NULL;
+
+ struct dwfl_relocation *sections = mod->reloc_info;
+
+ if (idx >= sections->count)
+ return NULL;
+
+ if (shndxp)
+ *shndxp = elf_ndxscn (sections->refs[idx].scn);
+
+ return sections->refs[idx].name;
+}
+
+int
+dwfl_module_relocate_address (Dwfl_Module *mod, Dwarf_Addr *addr)
+{
+ if (mod == NULL)
+ return -1;
+
+ if (mod->dw == NULL)
+ {
+ Dwarf_Addr bias;
+ if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
+ return -1;
+ }
+
+ if (mod->e_type != ET_REL)
+ {
+ *addr -= mod->debug.bias;
+ return 0;
+ }
+
+ if (unlikely (mod->reloc_info == NULL) && cache_sections (mod) < 0)
+ return -1;
+
+ struct dwfl_relocation *sections = mod->reloc_info;
+
+ /* The sections are sorted by address, so we can use binary search. */
+ size_t l = 0, u = sections->count;
+ while (l < u)
+ {
+ size_t idx = (l + u) / 2;
+ if (*addr < sections->refs[idx].start)
+ u = idx;
+ else if (*addr > sections->refs[idx].end)
+ l = idx + 1;
+ else
+ {
+ /* Consider the limit of a section to be inside it, unless it's
+ inside the next one. A section limit address can appear in
+ line records. */
+ if (*addr == sections->refs[idx].end
+ && idx < sections->count
+ && *addr == sections->refs[idx + 1].start)
+ ++idx;
+
+ *addr -= sections->refs[idx].start;
+ return idx;
+ }
+ }
+
+ __libdw_seterrno (DWARF_E_NO_MATCH);
+ return -1;
+}
+INTDEF (dwfl_module_relocate_address)
diff --git a/elfutils/libdwfl/dwfl_addrdie.c b/elfutils/libdwfl/dwfl_addrdie.c
new file mode 100644
index 00000000..4aba9c3e
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_addrdie.c
@@ -0,0 +1,21 @@
+/* Fetch CU DIE from address.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
+{
+ return INTUSE(dwfl_module_addrdie) (INTUSE(dwfl_addrmodule) (dwfl, addr),
+ addr, bias);
+}
diff --git a/elfutils/libdwfl/dwfl_addrdwarf.c b/elfutils/libdwfl/dwfl_addrdwarf.c
new file mode 100644
index 00000000..33eaec62
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_addrdwarf.c
@@ -0,0 +1,22 @@
+/* Fetch libdw handle from address.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwarf *
+dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Addr *bias)
+{
+ return INTUSE(dwfl_module_getdwarf) (INTUSE(dwfl_addrmodule) (dwfl, address),
+ bias);
+}
+INTDEF (dwfl_addrdwarf)
diff --git a/elfutils/libdwfl/dwfl_addrmodule.c b/elfutils/libdwfl/dwfl_addrmodule.c
new file mode 100644
index 00000000..69aab57c
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_addrmodule.c
@@ -0,0 +1,38 @@
+/* Find module containing address.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address)
+{
+ if (dwfl == NULL)
+ return NULL;
+
+ /* Do binary search on the array indexed by module load address. */
+ size_t l = 0, u = dwfl->nmodules;
+ while (l < u)
+ {
+ size_t idx = (l + u) / 2;
+ Dwfl_Module *m = dwfl->modules[idx];
+ if (address < m->low_addr)
+ u = idx;
+ else if (address >= m->high_addr)
+ l = idx + 1;
+ else
+ return m;
+ }
+
+ return NULL;
+}
+INTDEF (dwfl_addrmodule)
diff --git a/elfutils/libdwfl/dwfl_begin.c b/elfutils/libdwfl/dwfl_begin.c
new file mode 100644
index 00000000..f90d4b60
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_begin.c
@@ -0,0 +1,36 @@
+/* Set up a session using libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwfl *
+dwfl_begin (const Dwfl_Callbacks *callbacks)
+{
+ if (elf_version (EV_CURRENT) == EV_NONE)
+ {
+ __libdwfl_seterrno (DWFL_E_LIBELF);
+ return NULL;
+ }
+
+ Dwfl *dwfl = calloc (1, sizeof *dwfl);
+ if (dwfl == NULL)
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ else
+ {
+ dwfl->callbacks = callbacks;
+ dwfl->offline_next_address = OFFLINE_REDZONE;
+ }
+
+ return dwfl;
+}
+INTDEF (dwfl_begin)
diff --git a/elfutils/libdwfl/dwfl_cumodule.c b/elfutils/libdwfl/dwfl_cumodule.c
new file mode 100644
index 00000000..69b5c0fb
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_cumodule.c
@@ -0,0 +1,21 @@
+/* Find the module for a CU DIE previously returned by libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_cumodule (Dwarf_Die *cudie)
+{
+ struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
+ return cu->mod;
+}
diff --git a/elfutils/libdwfl/dwfl_end.c b/elfutils/libdwfl/dwfl_end.c
new file mode 100644
index 00000000..b2836d30
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_end.c
@@ -0,0 +1,26 @@
+/* Finish a session using libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+void
+dwfl_end (Dwfl *dwfl)
+{
+ if (dwfl != NULL)
+ {
+ for (size_t i = 0; i < dwfl->nmodules; ++i)
+ if (dwfl->modules[i] != NULL)
+ __libdwfl_module_free (dwfl->modules[i]);
+ free (dwfl->modules);
+ }
+}
diff --git a/elfutils/libdwfl/dwfl_error.c b/elfutils/libdwfl/dwfl_error.c
new file mode 100644
index 00000000..553c585f
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_error.c
@@ -0,0 +1,222 @@
+/* Error handling in libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "libdwflP.h"
+
+
+#ifdef USE_TLS
+/* The error number. */
+static __thread int global_error;
+#else
+/* This is the key for the thread specific memory. */
+static tls_key_t key;
+
+/* The error number. Used in non-threaded programs. */
+static int global_error;
+static bool threaded;
+/* We need to initialize the thread-specific data. */
+once_define (static, once);
+
+/* The initialization and destruction functions. */
+static void init (void);
+static void free_key_mem (void *mem);
+#endif /* TLS */
+
+
+int
+dwfl_errno (void)
+{
+ int result;
+
+#ifndef USE_TLS
+ /* If we have not yet initialized the buffer do it now. */
+ once_execute (once, init);
+
+ if (threaded)
+ {
+ /* We do not allocate memory for the data. It is only a word.
+ We can store it in place of the pointer. */
+ result = (intptr_t) getspecific (key);
+
+ setspecific (key, (void *) (intptr_t) DWFL_E_NOERROR);
+ return result;
+ }
+#endif /* TLS */
+
+ result = global_error;
+ global_error = DWFL_E_NOERROR;
+ return result;
+}
+
+
+static const struct msgtable
+{
+#define DWFL_ERROR(name, text) char msg_##name[sizeof text];
+ DWFL_ERRORS
+#undef DWFL_ERROR
+} msgtable =
+ {
+#define DWFL_ERROR(name, text) text,
+ DWFL_ERRORS
+#undef DWFL_ERROR
+ };
+#define msgstr (&msgtable.msg_NOERROR[0])
+
+static const uint_fast16_t msgidx[] =
+{
+#define DWFL_ERROR(name, text) \
+ [DWFL_E_##name] = offsetof (struct msgtable, msg_##name),
+ DWFL_ERRORS
+#undef DWFL_ERROR
+};
+#define nmsgidx (sizeof msgidx / sizeof msgidx[0])
+
+
+static inline int
+canonicalize (Dwfl_Error error)
+{
+ unsigned int value;
+
+ switch (error)
+ {
+ default:
+ value = error;
+ if ((value &~ 0xffff) != 0)
+ break;
+ assert (value < nmsgidx);
+ break;
+ case DWFL_E_ERRNO:
+ value = DWFL_E (ERRNO, errno);
+ break;
+ case DWFL_E_LIBELF:
+ value = DWFL_E (LIBELF, elf_errno ());
+ break;
+ case DWFL_E_LIBDW:
+ value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
+ break;
+#if 0
+ DWFL_E_LIBEBL:
+ value = DWFL_E (LIBEBL, ebl_errno ());
+ break;
+#endif
+ }
+
+ return value;
+}
+
+int
+internal_function_def
+__libdwfl_canon_error (Dwfl_Error error)
+{
+ return canonicalize (error);
+}
+
+void
+internal_function_def
+__libdwfl_seterrno (Dwfl_Error error)
+{
+ int value = canonicalize (error);
+
+#ifndef USE_TLS
+ /* If we have not yet initialized the buffer do it now. */
+ once_execute (once, init);
+
+ if (threaded)
+ /* We do not allocate memory for the data. It is only a word.
+ We can store it in place of the pointer. */
+ setspecific (key, (void *) (intptr_t) value);
+#endif /* TLS */
+
+ global_error = value;
+}
+
+
+const char *
+dwfl_errmsg (error)
+ int error;
+{
+ if (error == 0 || error == -1)
+ {
+ int last_error;
+
+#ifndef USE_TLS
+ /* If we have not yet initialized the buffer do it now. */
+ once_execute (once, init);
+
+ if (threaded)
+ /* We do not allocate memory for the data. It is only a word.
+ We can store it in place of the pointer. */
+ last_error = (intptr_t) getspecific (key);
+ else
+#endif /* TLS */
+ last_error = global_error;
+
+ if (error == 0 && last_error == 0)
+ return NULL;
+
+ error = last_error;
+ global_error = DWFL_E_NOERROR;
+ }
+
+ switch (error &~ 0xffff)
+ {
+ case OTHER_ERROR (ERRNO):
+ return strerror_r (error & 0xffff, "bad", 0);
+ case OTHER_ERROR (LIBELF):
+ return elf_errmsg (error & 0xffff);
+ case OTHER_ERROR (LIBDW):
+ return INTUSE(dwarf_errmsg) (error & 0xffff);
+#if 0
+ case OTHER_ERROR (LIBEBL):
+ return ebl_errmsg (error & 0xffff);
+#endif
+ }
+
+ return _(&msgstr[msgidx[(unsigned int) error < nmsgidx
+ ? error : DWFL_E_UNKNOWN_ERROR]]);
+}
+INTDEF (dwfl_errmsg)
+
+
+#ifndef USE_TLS
+/* Free the thread specific data, this is done if a thread terminates. */
+static void
+free_key_mem (void *mem __attribute__ ((unused)))
+{
+ setspecific (key, NULL);
+}
+
+
+/* Initialize the key for the global variable. */
+static void
+init (void)
+{
+ // XXX Screw you, gcc4, the unused function attribute does not work.
+ __asm ("" :: "r" (free_key_mem));
+
+ if (key_create (&key, free_key_mem) == 0)
+ /* Creating the key succeeded. */
+ threaded = true;
+}
+#endif /* TLS */
diff --git a/elfutils/libdwfl/dwfl_getdwarf.c b/elfutils/libdwfl/dwfl_getdwarf.c
new file mode 100644
index 00000000..cae49dab
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_getdwarf.c
@@ -0,0 +1,40 @@
+/* Iterate through modules to fetch Dwarf information.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+ptrdiff_t
+dwfl_getdwarf (Dwfl *dwfl,
+ int (*callback) (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr,
+ Dwarf *, Dwarf_Addr, void *),
+ void *arg,
+ ptrdiff_t offset)
+{
+ if (dwfl == NULL)
+ return -1;
+
+ if ((size_t) offset > dwfl->nmodules)
+ return -1;
+
+ while ((size_t) offset < dwfl->nmodules)
+ {
+ Dwfl_Module *mod = dwfl->modules[offset++];
+ Dwarf_Addr bias = 0;
+ Dwarf *dw = INTUSE(dwfl_module_getdwarf) (mod, &bias);
+ if ((*callback) (MODCB_ARGS (mod), dw, bias, arg) != DWARF_CB_OK)
+ return offset;
+ }
+
+ return 0;
+}
diff --git a/elfutils/libdwfl/dwfl_getmodules.c b/elfutils/libdwfl/dwfl_getmodules.c
new file mode 100644
index 00000000..4fc14880
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_getmodules.c
@@ -0,0 +1,37 @@
+/* Iterate through modules.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+ptrdiff_t
+dwfl_getmodules (Dwfl *dwfl,
+ int (*callback) (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr, void *),
+ void *arg,
+ ptrdiff_t offset)
+{
+ if (dwfl == NULL)
+ return -1;
+
+ if ((size_t) offset > dwfl->nmodules)
+ return -1;
+
+ while ((size_t) offset < dwfl->nmodules)
+ {
+ Dwfl_Module *mod = dwfl->modules[offset++];
+ if ((*callback) (MODCB_ARGS (mod), arg) != DWARF_CB_OK)
+ return offset;
+ }
+
+ return 0;
+}
diff --git a/elfutils/libdwfl/dwfl_getsrc.c b/elfutils/libdwfl/dwfl_getsrc.c
new file mode 100644
index 00000000..3ceb6329
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_getsrc.c
@@ -0,0 +1,21 @@
+/* Find source location for PC address.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwfl_Line *
+dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr)
+{
+ return INTUSE(dwfl_module_getsrc) (INTUSE(dwfl_addrmodule) (dwfl, addr),
+ addr);
+}
diff --git a/elfutils/libdwfl/dwfl_getsrclines.c b/elfutils/libdwfl/dwfl_getsrclines.c
new file mode 100644
index 00000000..0d1482ad
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_getsrclines.c
@@ -0,0 +1,33 @@
+/* Fetch source line information for CU.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+int
+dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines)
+{
+ struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
+
+ if (cu->lines == NULL)
+ {
+ Dwfl_Error error = __libdwfl_cu_getsrclines (cu);
+ if (error != DWFL_E_NOERROR)
+ {
+ __libdwfl_seterrno (error);
+ return -1;
+ }
+ }
+
+ *nlines = cu->die.cu->lines->nlines;
+ return -1;
+}
diff --git a/elfutils/libdwfl/dwfl_lineinfo.c b/elfutils/libdwfl/dwfl_lineinfo.c
new file mode 100644
index 00000000..4771e003
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_lineinfo.c
@@ -0,0 +1,40 @@
+/* Get information from a source line record returned by libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+extern const char *
+dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, int *linep, int *colp,
+ Dwarf_Word *mtime, Dwarf_Word *length)
+{
+ if (line == NULL)
+ return NULL;
+
+ struct dwfl_cu *cu = dwfl_linecu (line);
+ const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx];
+
+ if (addr != NULL)
+ *addr = info->addr - cu->mod->debug.bias;
+ if (linep != NULL)
+ *linep = info->line;
+ if (colp != NULL)
+ *colp = info->column;
+
+ struct Dwarf_Fileinfo_s *file = &info->files->info[info->file];
+ if (mtime != NULL)
+ *mtime = file->mtime;
+ if (length != NULL)
+ *length = file->length;
+ return file->name;
+}
diff --git a/elfutils/libdwfl/dwfl_linemodule.c b/elfutils/libdwfl/dwfl_linemodule.c
new file mode 100644
index 00000000..233dbd41
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_linemodule.c
@@ -0,0 +1,23 @@
+/* Fetch the module containing a source line record returned by libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_linemodule (Dwfl_Line *line)
+{
+ if (line == NULL)
+ return NULL;
+
+ return dwfl_linecu (line)->mod;
+}
diff --git a/elfutils/libdwfl/dwfl_module.c b/elfutils/libdwfl/dwfl_module.c
new file mode 100644
index 00000000..613c48de
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_module.c
@@ -0,0 +1,190 @@
+/* Maintenance of module list in libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include <search.h>
+
+static void
+free_cu (struct dwfl_cu *cu)
+{
+ if (cu->lines != NULL)
+ free (cu->lines);
+ free (cu);
+}
+
+static void
+nofree (void *arg __attribute__ ((unused)))
+{
+}
+
+void
+internal_function_def
+__libdwfl_module_free (Dwfl_Module *mod)
+{
+ if (mod->lazy_cu_root != NULL)
+ tdestroy (mod->lazy_cu_root, nofree);
+
+ if (mod->aranges != NULL)
+ free (mod->aranges);
+
+ if (mod->cu != NULL)
+ {
+ for (size_t i = 0; i < mod->ncu; ++i)
+ free_cu (mod->cu[i]);
+ free (mod->cu);
+ }
+
+ if (mod->dw != NULL)
+ INTUSE(dwarf_end) (mod->dw);
+
+ if (mod->ebl != NULL)
+ ebl_closebackend (mod->ebl);
+
+ if (mod->debug.elf != mod->main.elf && mod->debug.elf != NULL)
+ elf_end (mod->debug.elf);
+ if (mod->main.elf != NULL)
+ elf_end (mod->main.elf);
+
+ free (mod->name);
+}
+
+void
+dwfl_report_begin (Dwfl *dwfl)
+{
+ for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
+ m->gc = true;
+
+ if (dwfl->modules != NULL)
+ free (dwfl->modules);
+ dwfl->modules = NULL;
+ dwfl->nmodules = 0;
+
+ dwfl->offline_next_address = OFFLINE_REDZONE;
+}
+INTDEF (dwfl_report_begin)
+
+/* Report that a module called NAME pans addresses [START, END).
+ Returns the module handle, either existing or newly allocated,
+ or returns a null pointer for an allocation error. */
+Dwfl_Module *
+dwfl_report_module (Dwfl *dwfl, const char *name,
+ GElf_Addr start, GElf_Addr end)
+{
+ Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
+ for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
+ {
+ if (m->low_addr == start && m->high_addr == end
+ && !strcmp (m->name, name))
+ {
+ /* This module is still here. Move it to the place in the list
+ after the last module already reported. */
+
+ *prevp = m->next;
+ m->next = *tailp;
+ m->gc = false;
+ *tailp = m;
+ return m;
+ }
+
+ if (! m->gc)
+ tailp = &m->next;
+ }
+
+ Dwfl_Module *mod = calloc (1, sizeof *mod);
+ if (mod == NULL)
+ goto nomem;
+
+ mod->name = strdup (name);
+ if (mod->name == NULL)
+ {
+ free (mod);
+ nomem:
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return NULL;
+ }
+
+ mod->low_addr = start;
+ mod->high_addr = end;
+ mod->dwfl = dwfl;
+
+ mod->next = *tailp;
+ *tailp = mod;
+ ++dwfl->nmodules;
+
+ return mod;
+}
+INTDEF (dwfl_report_module)
+
+static int
+compare_modules (const void *a, const void *b)
+{
+ Dwfl_Module *const *p1 = a, *const *p2 = b;
+ const Dwfl_Module *m1 = *p1, *m2 = *p2;
+ if (m1 == NULL)
+ return -1;
+ if (m2 == NULL)
+ return 1;
+ return (GElf_Sxword) (m1->low_addr - m2->low_addr);
+}
+
+
+/* Finish reporting the current set of modules to the library.
+ If REMOVED is not null, it's called for each module that
+ existed before but was not included in the current report.
+ Returns a nonzero return value from the callback.
+ DWFL cannot be used until this function has returned zero. */
+int dwfl_report_end (Dwfl *dwfl,
+ int (*removed) (Dwfl_Module *, void *,
+ const char *, Dwarf_Addr,
+ void *arg),
+ void *arg)
+{
+ assert (dwfl->modules == NULL);
+
+ Dwfl_Module **tailp = &dwfl->modulelist;
+ while (*tailp != NULL)
+ {
+ Dwfl_Module *m = *tailp;
+ if (m->gc && removed != NULL)
+ {
+ int result = (*removed) (MODCB_ARGS (m), arg);
+ if (result != 0)
+ return result;
+ }
+ if (m->gc)
+ {
+ *tailp = m->next;
+ __libdwfl_module_free (m);
+ }
+ else
+ tailp = &m->next;
+ }
+
+ dwfl->modules = malloc (dwfl->nmodules * sizeof dwfl->modules[0]);
+ if (dwfl->modules == NULL && dwfl->nmodules != 0)
+ return -1;
+
+ size_t i = 0;
+ for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
+ {
+ assert (! m->gc);
+ dwfl->modules[i++] = m;
+ }
+ assert (i == dwfl->nmodules);
+
+ qsort (dwfl->modules, dwfl->nmodules, sizeof dwfl->modules[0],
+ &compare_modules);
+
+ return 0;
+}
+INTDEF (dwfl_report_end)
diff --git a/elfutils/libdwfl/dwfl_module_addrdie.c b/elfutils/libdwfl/dwfl_module_addrdie.c
new file mode 100644
index 00000000..29e2dfe8
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_module_addrdie.c
@@ -0,0 +1,30 @@
+/* Fetch the CU DIE for a PC address in a given module.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_module_addrdie (Dwfl_Module *mod, Dwarf_Addr addr, Dwarf_Addr *bias)
+{
+ if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL)
+ return NULL;
+
+ struct dwfl_cu *cu;
+ Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu);
+ if (likely (error == DWFL_E_NOERROR))
+ return &cu->die;
+
+ __libdwfl_seterrno (error);
+ return NULL;
+}
+INTDEF (dwfl_module_addrdie)
diff --git a/elfutils/libdwfl/dwfl_module_getdwarf.c b/elfutils/libdwfl/dwfl_module_getdwarf.c
new file mode 100644
index 00000000..50245750
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_module_getdwarf.c
@@ -0,0 +1,496 @@
+/* Find debugging and symbol information for a module in libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include "../libdw/libdwP.h" /* DWARF_E_* values are here. */
+
+
+/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD.
+ When we return success, FILE->elf and FILE->bias are set up. */
+static inline Dwfl_Error
+open_elf (Dwfl_Module *mod, struct dwfl_file *file)
+{
+ if (file->elf == NULL)
+ {
+ if (file->fd < 0)
+ return CBFAIL;
+
+ file->elf = elf_begin (file->fd, ELF_C_READ_MMAP_PRIVATE, NULL);
+ }
+
+ GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
+ if (ehdr == NULL)
+ return DWFL_E (LIBELF, elf_errno ());
+
+ mod->e_type = ehdr->e_type;
+
+ file->bias = 0;
+ 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)
+ return DWFL_E_LIBELF;
+ if (ph->p_type == PT_LOAD)
+ {
+ file->bias = ((mod->low_addr & -ph->p_align)
+ - (ph->p_vaddr & -ph->p_align));
+ break;
+ }
+ }
+
+ return DWFL_E_NOERROR;
+}
+
+/* Find the main ELF file for this module and open libelf on it.
+ When we return success, MOD->main.elf and MOD->main.bias are set up. */
+static void
+find_file (Dwfl_Module *mod)
+{
+ if (mod->main.elf != NULL /* Already done. */
+ || mod->elferr != DWFL_E_NOERROR) /* Cached failure. */
+ return;
+
+ mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod),
+ &mod->main.name,
+ &mod->main.elf);
+ mod->elferr = open_elf (mod, &mod->main);
+}
+
+/* Find the separate debuginfo file for this module and open libelf on it.
+ When we return success, MOD->debug is set up. */
+static Dwfl_Error
+find_debuginfo (Dwfl_Module *mod)
+{
+ if (mod->debug.elf != NULL)
+ return DWFL_E_NOERROR;
+
+ size_t shstrndx;
+ if (elf_getshstrndx (mod->main.elf, &shstrndx) < 0)
+ return DWFL_E_LIBELF;
+
+ Elf_Scn *scn = elf_getscn (mod->main.elf, 0);
+ if (scn == NULL)
+ return DWFL_E_LIBELF;
+ do
+ {
+ GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr == NULL)
+ return DWFL_E_LIBELF;
+
+ const char *name = elf_strptr (mod->main.elf, shstrndx, shdr->sh_name);
+ if (name == NULL)
+ return DWFL_E_LIBELF;
+
+ if (!strcmp (name, ".gnu_debuglink"))
+ break;
+
+ scn = elf_nextscn (mod->main.elf, scn);
+ } while (scn != NULL);
+
+ const char *debuglink_file = NULL;
+ GElf_Word debuglink_crc = 0;
+ if (scn != NULL)
+ {
+ /* Found the .gnu_debuglink section. Extract its contents. */
+ Elf_Data *rawdata = elf_rawdata (scn, NULL);
+ if (rawdata == NULL)
+ return DWFL_E_LIBELF;
+
+ Elf_Data crcdata =
+ {
+ .d_type = ELF_T_WORD,
+ .d_buf = &debuglink_crc,
+ .d_size = sizeof debuglink_crc,
+ .d_version = EV_CURRENT,
+ };
+ Elf_Data conv =
+ {
+ .d_type = ELF_T_WORD,
+ .d_buf = rawdata->d_buf + rawdata->d_size - sizeof debuglink_crc,
+ .d_size = sizeof debuglink_crc,
+ .d_version = EV_CURRENT,
+ };
+
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem);
+ if (ehdr == NULL)
+ return DWFL_E_LIBELF;
+
+ Elf_Data *d = gelf_xlatetom (mod->main.elf, &crcdata, &conv,
+ ehdr->e_ident[EI_DATA]);
+ if (d == NULL)
+ return DWFL_E_LIBELF;
+ assert (d == &crcdata);
+
+ debuglink_file = rawdata->d_buf;
+ }
+
+ mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
+ mod->main.name,
+ debuglink_file,
+ debuglink_crc,
+ &mod->debug.name);
+ return open_elf (mod, &mod->debug);
+}
+
+
+/* Try to find a symbol table in FILE. */
+static Dwfl_Error
+load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
+ Elf_Scn **symscn, Elf_Scn **xndxscn,
+ size_t *syments, GElf_Word *strshndx)
+{
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (file->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr != NULL)
+ switch (shdr->sh_type)
+ {
+ case SHT_SYMTAB:
+ *symscn = scn;
+ *symfile = file;
+ *strshndx = shdr->sh_link;
+ *syments = shdr->sh_size / shdr->sh_entsize;
+ if (*symscn != NULL && *xndxscn != NULL)
+ return DWFL_E_NOERROR;
+ break;
+
+ case SHT_DYNSYM:
+ /* Use this if need be, but keep looking for SHT_SYMTAB. */
+ *symscn = scn;
+ *symfile = file;
+ *strshndx = shdr->sh_link;
+ *syments = shdr->sh_size / shdr->sh_entsize;
+ break;
+
+ case SHT_SYMTAB_SHNDX:
+ *xndxscn = scn;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return DWFL_E_NO_SYMTAB;
+}
+
+/* Try to find a symbol table in either MOD->main.elf or MOD->debug.elf. */
+static void
+find_symtab (Dwfl_Module *mod)
+{
+ if (mod->symdata != NULL /* Already done. */
+ || mod->symerr != DWFL_E_NOERROR) /* Cached previous failure. */
+ return;
+
+ find_file (mod);
+ mod->symerr = mod->elferr;
+ if (mod->symerr != DWFL_E_NOERROR)
+ return;
+
+ /* First see if the main ELF file has the debugging information. */
+ Elf_Scn *symscn = NULL, *xndxscn = NULL;
+ GElf_Word strshndx;
+ mod->symerr = load_symtab (&mod->main, &mod->symfile, &symscn,
+ &xndxscn, &mod->syments, &strshndx);
+ switch (mod->symerr)
+ {
+ default:
+ return;
+
+ case DWFL_E_NOERROR:
+ break;
+
+ case DWFL_E_NO_SYMTAB:
+ /* Now we have to look for a separate debuginfo file. */
+ mod->symerr = find_debuginfo (mod);
+ switch (mod->symerr)
+ {
+ default:
+ return;
+
+ case DWFL_E_NOERROR:
+ mod->symerr = load_symtab (&mod->debug, &mod->symfile, &symscn,
+ &xndxscn, &mod->syments, &strshndx);
+ break;
+
+ case DWFL_E_CB: /* The find_debuginfo hook failed. */
+ mod->symerr = DWFL_E_NO_SYMTAB;
+ break;
+ }
+
+ switch (mod->symerr)
+ {
+ default:
+ return;
+
+ case DWFL_E_NOERROR:
+ break;
+
+ case DWFL_E_NO_SYMTAB:
+ if (symscn == NULL)
+ return;
+ /* We still have the dynamic symbol table. */
+ mod->symerr = DWFL_E_NOERROR;
+ break;
+ }
+ break;
+ }
+
+ /* This does some sanity checks on the string table section. */
+ if (elf_strptr (mod->symfile->elf, strshndx, 0) == NULL)
+ {
+ elferr:
+ mod->symerr = DWFL_E (LIBELF, elf_errno ());
+ return;
+ }
+
+ /* Cache the data; MOD->syments was set above. */
+
+ mod->symstrdata = elf_getdata (elf_getscn (mod->symfile->elf, strshndx),
+ NULL);
+ if (mod->symstrdata == NULL)
+ goto elferr;
+
+ if (xndxscn == NULL)
+ mod->symxndxdata = NULL;
+ else
+ {
+ mod->symxndxdata = elf_getdata (xndxscn, NULL);
+ if (mod->symxndxdata == NULL)
+ goto elferr;
+ }
+
+ mod->symdata = elf_getdata (symscn, NULL);
+ if (mod->symdata == NULL)
+ goto elferr;
+}
+
+
+/* Try to start up libdw on DEBUGFILE. */
+static Dwfl_Error
+load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
+{
+ if (mod->e_type == ET_REL)
+ {
+ const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
+
+ /* The debugging sections have to be relocated. */
+ if (cb->section_address == NULL)
+ return DWFL_E_NOREL;
+
+ if (mod->ebl == NULL)
+ {
+ mod->ebl = ebl_openbackend (mod->main.elf);
+ if (mod->ebl == NULL)
+ return DWFL_E_LIBEBL;
+ }
+
+ find_symtab (mod);
+ Dwfl_Error result = mod->symerr;
+ if (result == DWFL_E_NOERROR)
+ result = __libdwfl_relocate (mod, debugfile->elf);
+ 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)
+ {
+ int err = INTUSE(dwarf_errno) ();
+ return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err);
+ }
+
+ /* Until we have iterated through all CU's, we might do lazy lookups. */
+ mod->lazycu = 1;
+
+ return DWFL_E_NOERROR;
+}
+
+/* Try to start up libdw on either the main file or the debuginfo file. */
+static void
+find_dw (Dwfl_Module *mod)
+{
+ if (mod->dw != NULL /* Already done. */
+ || mod->dwerr != DWFL_E_NOERROR) /* Cached previous failure. */
+ return;
+
+ find_file (mod);
+ mod->dwerr = mod->elferr;
+ if (mod->dwerr != DWFL_E_NOERROR)
+ return;
+
+ /* First see if the main ELF file has the debugging information. */
+ mod->dwerr = load_dw (mod, &mod->main);
+ switch (mod->dwerr)
+ {
+ case DWFL_E_NOERROR:
+ mod->debug.elf = mod->main.elf;
+ mod->debug.bias = mod->main.bias;
+ return;
+
+ case DWFL_E_NO_DWARF:
+ break;
+
+ default:
+ goto canonicalize;
+ }
+
+ /* Now we have to look for a separate debuginfo file. */
+ mod->dwerr = find_debuginfo (mod);
+ switch (mod->dwerr)
+ {
+ case DWFL_E_NOERROR:
+ mod->dwerr = load_dw (mod, &mod->debug);
+ break;
+
+ case DWFL_E_CB: /* The find_debuginfo hook failed. */
+ mod->dwerr = DWFL_E_NO_DWARF;
+ return;
+
+ default:
+ break;
+ }
+
+ canonicalize:
+ mod->dwerr = __libdwfl_canon_error (mod->dwerr);
+}
+
+
+Elf *
+dwfl_module_getelf (Dwfl_Module *mod, GElf_Addr *loadbase)
+{
+ if (mod == NULL)
+ return NULL;
+
+ find_file (mod);
+ if (mod->elferr == DWFL_E_NOERROR)
+ {
+ *loadbase = mod->main.bias;
+ return mod->main.elf;
+ }
+
+ __libdwfl_seterrno (mod->elferr);
+ return NULL;
+}
+INTDEF (dwfl_module_getelf)
+
+
+Dwarf *
+dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
+{
+ if (mod == NULL)
+ return NULL;
+
+ find_dw (mod);
+ if (mod->dwerr == DWFL_E_NOERROR)
+ {
+ *bias = mod->debug.bias;
+ return mod->dw;
+ }
+
+ __libdwfl_seterrno (mod->dwerr);
+ return NULL;
+}
+INTDEF (dwfl_module_getdwarf)
+
+
+const char *
+dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr addr)
+{
+ if (mod == NULL)
+ return NULL;
+
+ find_symtab (mod);
+ if (mod->symerr != DWFL_E_NOERROR)
+ {
+ __libdwfl_seterrno (mod->symerr);
+ return NULL;
+ }
+
+ addr -= mod->symfile->bias;
+
+ /* Look through the symbol table for a matching symbol. */
+ size_t symshstrndx = SHN_UNDEF;
+ for (size_t i = 1; i < mod->syments; ++i)
+ {
+ GElf_Sym sym_mem;
+ GElf_Word shndx;
+ GElf_Sym *sym = gelf_getsymshndx (mod->symdata, mod->symxndxdata,
+ i, &sym_mem, &shndx);
+ if (sym != NULL)
+ {
+ GElf_Addr symaddr = sym->st_value;
+
+ if (sym->st_shndx != SHN_XINDEX)
+ shndx = sym->st_shndx;
+
+ if (mod->e_type == ET_REL)
+ /* In an ET_REL file, the symbol table values are relative
+ to the section, not to the module's load base. */
+ switch (shndx)
+ {
+ case SHN_UNDEF: /* Undefined symbol can't match an address. */
+ case SHN_COMMON: /* Nor can a common defn. */
+ continue;
+
+ case SHN_ABS: /* Symbol value is already absolute. */
+ break;
+
+ default:
+ {
+ Dwfl_Error result = DWFL_E_LIBELF;
+ if (likely (symshstrndx != SHN_UNDEF)
+ || elf_getshstrndx (mod->symfile->elf,
+ &symshstrndx) == 0)
+ result = __libdwfl_relocate_value (mod, symshstrndx,
+ shndx, &symaddr);
+ if (unlikely (result != DWFL_E_NOERROR))
+ {
+ __libdwfl_seterrno (result);
+ return NULL;
+ }
+ break;
+ }
+ }
+
+ if (symaddr <= addr && addr < symaddr + sym->st_size)
+ {
+ if (unlikely (sym->st_name >= mod->symstrdata->d_size))
+ {
+ __libdwfl_seterrno (DWFL_E_BADSTROFF);
+ return NULL;
+ }
+ return (const char *) mod->symstrdata->d_buf + sym->st_name;
+ }
+ }
+ }
+
+ return NULL;
+}
diff --git a/elfutils/libdwfl/dwfl_module_getsrc.c b/elfutils/libdwfl/dwfl_module_getsrc.c
new file mode 100644
index 00000000..3b341b92
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_module_getsrc.c
@@ -0,0 +1,60 @@
+/* Find source location for PC address in module.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+Dwfl_Line *
+dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr)
+{
+ Dwarf_Addr bias;
+ if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
+ return NULL;
+
+ struct dwfl_cu *cu;
+ Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu);
+ if (likely (error == DWFL_E_NOERROR))
+ error = __libdwfl_cu_getsrclines (cu);
+ if (likely (error == DWFL_E_NOERROR))
+ {
+ /* 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)
+ {
+ size_t idx = (l + u) / 2;
+ if (addr < cu->die.cu->lines->info[idx].addr)
+ u = idx;
+ else if (addr > cu->die.cu->lines->info[idx].addr)
+ l = idx + 1;
+ else
+ return &cu->lines->idx[idx];
+ }
+
+ if (cu->die.cu->lines->nlines > 0)
+ assert (cu->die.cu->lines->info
+ [cu->die.cu->lines->nlines - 1].end_sequence);
+
+ /* If none were equal, the closest one below is what we want.
+ We never want the last one, because it's the end-sequence
+ marker with an address at the high bound of the CU's code. */
+ if (u > 0 && u < cu->die.cu->lines->nlines
+ && addr > cu->die.cu->lines->info[u - 1].addr)
+ return &cu->lines->idx[u - 1];
+
+ error = DWFL_E_ADDR_OUTOFRANGE;
+ }
+
+ __libdwfl_seterrno (error);
+ return NULL;
+}
+INTDEF (dwfl_module_getsrc)
diff --git a/elfutils/libdwfl/dwfl_module_getsrc_file.c b/elfutils/libdwfl/dwfl_module_getsrc_file.c
new file mode 100644
index 00000000..640899d0
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_module_getsrc_file.c
@@ -0,0 +1,152 @@
+/* Find matching source locations in a module.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+
+int
+dwfl_module_getsrc_file (Dwfl_Module *mod,
+ const char *fname, int lineno, int column,
+ Dwfl_Line ***srcsp, size_t *nsrcs)
+{
+ if (mod == NULL)
+ return -1;
+
+ if (mod->dw == NULL)
+ {
+ Dwarf_Addr bias;
+ if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
+ return -1;
+ }
+
+ bool is_basename = strchr (fname, '/') == NULL;
+
+ size_t max_match = *nsrcs ?: ~0u;
+ size_t act_match = *nsrcs;
+ size_t cur_match = 0;
+ Dwfl_Line **match = *nsrcs == 0 ? NULL : *srcsp;
+
+ struct dwfl_cu *cu = NULL;
+ Dwfl_Error error;
+ while ((error = __libdwfl_nextcu (mod, cu, &cu)) == DWFL_E_NOERROR
+ && cu != NULL
+ && (error = __libdwfl_cu_getsrclines (cu)) == DWFL_E_NOERROR)
+ {
+ inline const char *INTUSE(dwarf_line_file) (const Dwarf_Line *line)
+ {
+ return line->files->info[line->file].name;
+ }
+ inline Dwarf_Line *dwfl_line (const Dwfl_Line *line)
+ {
+ return &dwfl_linecu (line)->die.cu->lines->info[line->idx];
+ }
+ inline const char *dwfl_line_file (const Dwfl_Line *line)
+ {
+ return INTUSE(dwarf_line_file) (dwfl_line (line));
+ }
+
+ /* Search through all the line number records for a matching
+ file and line/column number. If any of the numbers is zero,
+ no match is performed. */
+ const char *lastfile = NULL;
+ bool lastmatch = false;
+ for (size_t cnt = 0; cnt < cu->die.cu->lines->nlines; ++cnt)
+ {
+ Dwarf_Line *line = &cu->die.cu->lines->info[cnt];
+
+ if (unlikely (line->file >= line->files->nfiles))
+ {
+ __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF));
+ return -1;
+ }
+ else
+ {
+ const char *file = INTUSE(dwarf_line_file) (line);
+ if (file != lastfile)
+ {
+ /* Match the name with the name the user provided. */
+ lastfile = file;
+ lastmatch = !strcmp (is_basename ? basename (file) : file,
+ fname);
+ }
+ }
+ if (!lastmatch)
+ continue;
+
+ /* See whether line and possibly column match. */
+ if (lineno != 0
+ && (lineno > line->line
+ || (column != 0 && column > line->column)))
+ /* Cannot match. */
+ continue;
+
+ /* Determine whether this is the best match so far. */
+ size_t inner;
+ for (inner = 0; inner < cur_match; ++inner)
+ if (dwfl_line_file (match[inner])
+ == INTUSE(dwarf_line_file) (line))
+ break;
+ if (inner < cur_match
+ && (dwfl_line (match[inner])->line != line->line
+ || dwfl_line (match[inner])->line != lineno
+ || (column != 0
+ && (dwfl_line (match[inner])->column != line->column
+ || dwfl_line (match[inner])->column != column))))
+ {
+ /* We know about this file already. If this is a better
+ match for the line number, use it. */
+ if (dwfl_line (match[inner])->line >= line->line
+ && (dwfl_line (match[inner])->line != line->line
+ || dwfl_line (match[inner])->column >= line->column))
+ /* Use the new line. Otherwise the old one. */
+ match[inner] = &cu->lines->idx[cnt];
+ continue;
+ }
+
+ if (cur_match < max_match)
+ {
+ if (cur_match == act_match)
+ {
+ /* Enlarge the array for the results. */
+ act_match += 10;
+ Dwfl_Line **newp = realloc (match,
+ act_match
+ * sizeof (Dwfl_Line *));
+ if (newp == NULL)
+ {
+ free (match);
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return -1;
+ }
+ match = newp;
+ }
+
+ match[cur_match++] = &cu->lines->idx[cnt];
+ }
+ }
+ }
+
+ if (cur_match > 0)
+ {
+ assert (*nsrcs == 0 || *srcsp == match);
+
+ *nsrcs = cur_match;
+ *srcsp = match;
+
+ return 0;
+ }
+
+ __libdwfl_seterrno (DWFL_E_NO_MATCH);
+ return -1;
+}
diff --git a/elfutils/libdwfl/dwfl_module_info.c b/elfutils/libdwfl/dwfl_module_info.c
new file mode 100644
index 00000000..e8c27b9d
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_module_info.c
@@ -0,0 +1,44 @@
+/* Return information about a module.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+const char *
+dwfl_module_info (Dwfl_Module *mod, void ***userdata,
+ Dwarf_Addr *start, Dwarf_Addr *end,
+ Dwarf_Addr *dwbias, Dwarf_Addr *symbias,
+ const char **mainfile, const char **debugfile)
+{
+ if (mod == NULL)
+ return NULL;
+
+ if (userdata)
+ *userdata = &mod->userdata;
+ if (start)
+ *start = mod->low_addr;
+ if (end)
+ *end = mod->high_addr;
+
+ if (dwbias)
+ *dwbias = mod->debug.elf == NULL ? (Dwarf_Addr) -1 : mod->debug.bias;
+ if (symbias)
+ *symbias = mod->symfile == NULL ? (Dwarf_Addr) -1 : mod->symfile->bias;
+
+ if (mainfile)
+ *mainfile = mod->main.name;
+
+ if (debugfile)
+ *debugfile = mod->debug.name;
+
+ return mod->name;
+}
diff --git a/elfutils/libdwfl/dwfl_module_nextcu.c b/elfutils/libdwfl/dwfl_module_nextcu.c
new file mode 100644
index 00000000..c089047f
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_module_nextcu.c
@@ -0,0 +1,29 @@
+/* Iterate through DWARF compilation units in a module.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_module_nextcu (Dwfl_Module *mod, Dwarf_Die *lastcu, Dwarf_Addr *bias)
+{
+ if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL)
+ return NULL;
+
+ struct dwfl_cu *cu;
+ Dwfl_Error error = __libdwfl_nextcu (mod, (struct dwfl_cu *) lastcu, &cu);
+ if (likely (error == DWFL_E_NOERROR))
+ return &cu->die; /* Same as a cast, so ok for null too. */
+
+ __libdwfl_seterrno (error);
+ return NULL;
+}
diff --git a/elfutils/libdwfl/dwfl_nextcu.c b/elfutils/libdwfl/dwfl_nextcu.c
new file mode 100644
index 00000000..a5565c69
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_nextcu.c
@@ -0,0 +1,52 @@
+/* Iterate through DWARF compilation units across all modules.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias)
+{
+ if (dwfl == NULL)
+ return NULL;
+
+ struct dwfl_cu *cu = (struct dwfl_cu *) lastcu;
+ Dwfl_Module *mod;
+
+ if (cu == NULL)
+ {
+ mod = dwfl->modulelist;
+ goto nextmod;
+ }
+ else
+ mod = cu->mod;
+
+ Dwfl_Error error;
+ while ((error = __libdwfl_nextcu (mod, cu, &cu)) == DWFL_E_NOERROR)
+ {
+ if (cu != NULL)
+ {
+ *bias = mod->debug.bias;
+ return &cu->die;
+ }
+
+ mod = mod->next;
+
+ nextmod:
+ if (mod == NULL || INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL)
+ return NULL;
+ }
+
+ __libdwfl_seterrno (error);
+ return NULL;
+}
+INTDEF (dwfl_nextcu)
diff --git a/elfutils/libdwfl/dwfl_onesrcline.c b/elfutils/libdwfl/dwfl_onesrcline.c
new file mode 100644
index 00000000..3b09de02
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_onesrcline.c
@@ -0,0 +1,41 @@
+/* Return one of the sources lines of a CU.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+Dwfl_Line *
+dwfl_onesrcline (Dwarf_Die *cudie, size_t idx)
+{
+ struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
+
+ if (cudie == NULL)
+ return NULL;
+
+ if (cu->lines == NULL)
+ {
+ Dwfl_Error error = __libdwfl_cu_getsrclines (cu);
+ if (error != DWFL_E_NOERROR)
+ {
+ __libdwfl_seterrno (error);
+ return NULL;
+ }
+ }
+
+ if (idx >= cu->die.cu->lines->nlines)
+ {
+ __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_LINE_IDX));
+ return NULL;
+ }
+
+ return &cu->lines->idx[idx];
+}
diff --git a/elfutils/libdwfl/dwfl_report_elf.c b/elfutils/libdwfl/dwfl_report_elf.c
new file mode 100644
index 00000000..82545631
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_report_elf.c
@@ -0,0 +1,171 @@
+/* Report a module to libdwfl based on ELF program headers.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+
+Dwfl_Module *
+dwfl_report_elf (Dwfl *dwfl, const char *name,
+ const char *file_name, int fd, GElf_Addr base)
+{
+ bool closefd = false;
+
+ if (fd < 0)
+ {
+ fd = open64 (file_name, O_RDONLY);
+ if (fd < 0)
+ {
+ __libdwfl_seterrno (DWFL_E_ERRNO);
+ return NULL;
+ }
+ closefd = true;
+ }
+
+ Elf *elf = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, NULL);
+
+ GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ if (ehdr == NULL)
+ {
+ elf_error:
+ __libdwfl_seterrno (DWFL_E_LIBELF);
+ if (closefd)
+ close (fd);
+ return NULL;
+ }
+
+ GElf_Addr start = 0, end = 0, bias = 0;
+ switch (ehdr->e_type)
+ {
+ case ET_REL:
+ /* For a relocatable object, we do an arbitrary section layout.
+ By updating the section header in place, we leave the layout
+ information to be found by relocation. */
+
+ start = end = base;
+
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr == NULL)
+ goto elf_error;
+
+ if (shdr->sh_flags & SHF_ALLOC)
+ {
+ const GElf_Xword align = shdr->sh_addralign ?: 1;
+ shdr->sh_addr = (end + align - 1) & -align;
+ if (end == base)
+ /* This is the first section assigned a location.
+ Use its aligned address as the module's base. */
+ start = shdr->sh_addr;
+ end = shdr->sh_addr + shdr->sh_size;
+ if (! gelf_update_shdr (scn, shdr))
+ goto elf_error;
+ }
+ }
+
+ if (end == start)
+ {
+ __libdwfl_seterrno (DWFL_E_BADELF);
+ if (closefd)
+ close (fd);
+ return NULL;
+ }
+ break;
+
+ /* Everything else has to have program headers. */
+
+ case ET_EXEC:
+ case ET_CORE:
+ /* An assigned base address is meaningless for these. */
+ base = 0;
+
+ case ET_DYN:
+ default:
+ for (uint_fast16_t i = 0; i < ehdr->e_phnum; ++i)
+ {
+ GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
+ if (ph == NULL)
+ goto elf_error;
+ if (ph->p_type == PT_LOAD)
+ {
+ if ((base & (ph->p_align - 1)) != 0)
+ base = (base + ph->p_align - 1) & -ph->p_align;
+ start = base + (ph->p_vaddr & -ph->p_align);
+ break;
+ }
+ }
+ bias = base;
+
+ for (uint_fast16_t i = ehdr->e_phnum; i-- > 0;)
+ {
+ GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
+ if (ph == NULL)
+ goto elf_error;
+ if (ph->p_type == PT_LOAD)
+ {
+ end = base + (ph->p_vaddr + ph->p_memsz);
+ break;
+ }
+ }
+
+ if (end == 0)
+ {
+ __libdwfl_seterrno (DWFL_E_NO_PHDR);
+ if (closefd)
+ close (fd);
+ return NULL;
+ }
+ break;
+ }
+
+ Dwfl_Module *m = INTUSE(dwfl_report_module) (dwfl, name, start, end);
+ if (m != NULL)
+ {
+ if (m->main.name == NULL)
+ {
+ m->main.name = strdup (file_name);
+ m->main.fd = fd;
+ }
+ else if ((fd >= 0 && m->main.fd != fd)
+ || strcmp (m->main.name, file_name))
+ {
+ elf_end (elf);
+ overlap:
+ if (closefd)
+ close (fd);
+ m->gc = true;
+ __libdwfl_seterrno (DWFL_E_OVERLAP);
+ m = NULL;
+ }
+
+ /* Preinstall the open ELF handle for the module. */
+ if (m->main.elf == NULL)
+ {
+ m->main.elf = elf;
+ m->main.bias = bias;
+ m->e_type = ehdr->e_type;
+ }
+ else
+ {
+ elf_end (elf);
+ if (m->main.bias != base)
+ goto overlap;
+ }
+ }
+ return m;
+}
+INTDEF (dwfl_report_elf)
diff --git a/elfutils/libdwfl/dwfl_validate_address.c b/elfutils/libdwfl/dwfl_validate_address.c
new file mode 100644
index 00000000..b828f17e
--- /dev/null
+++ b/elfutils/libdwfl/dwfl_validate_address.c
@@ -0,0 +1,46 @@
+/* Validate an address and the relocatability of an offset from it.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+int
+dwfl_validate_address (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Sword offset)
+{
+ Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (dwfl, address);
+ if (mod == NULL)
+ return -1;
+
+ Dwarf_Addr relative = address;
+ int idx = INTUSE(dwfl_module_relocate_address) (mod, &relative);
+ if (idx < 0)
+ return -1;
+
+ if (offset != 0)
+ {
+ int offset_idx = -1;
+ relative = address + offset;
+ if (relative >= mod->low_addr && relative <= mod->high_addr)
+ {
+ offset_idx = INTUSE(dwfl_module_relocate_address) (mod, &relative);
+ if (offset_idx < 0)
+ return -1;
+ }
+ if (offset_idx != idx)
+ {
+ __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE);
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/elfutils/libdwfl/elf-from-memory.c b/elfutils/libdwfl/elf-from-memory.c
new file mode 100644
index 00000000..3175ab16
--- /dev/null
+++ b/elfutils/libdwfl/elf-from-memory.c
@@ -0,0 +1,328 @@
+/* Reconstruct an ELF file by reading the segments out of remote memory.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include <config.h>
+#include "../libelf/libelfP.h"
+#undef _
+
+#include "libdwflP.h"
+
+#include <gelf.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Reconstruct an ELF file by reading the segments out of remote memory
+ based on the ELF file header at EHDR_VMA and the ELF program headers it
+ points to. If not null, *LOADBASEP is filled in with the difference
+ between the addresses from which the segments were read, and the
+ addresses the file headers put them at.
+
+ The function READ_MEMORY is called to copy at least MINREAD and at most
+ MAXREAD bytes from the remote memory at target address ADDRESS into the
+ local buffer at DATA; it should return -1 for errors (with code in
+ `errno'), 0 if it failed to read at least MINREAD bytes due to EOF, or
+ the number of bytes read if >= MINREAD. ARG is passed through. */
+
+Elf *
+elf_from_remote_memory (GElf_Addr ehdr_vma,
+ GElf_Addr *loadbasep,
+ ssize_t (*read_memory) (void *arg, void *data,
+ GElf_Addr address,
+ size_t minread,
+ size_t maxread),
+ void *arg)
+{
+ /* First read in the file header and check its sanity. */
+
+ const size_t initial_bufsize = 256;
+ unsigned char *buffer = malloc (initial_bufsize);
+ if (buffer == NULL)
+ {
+ no_memory:
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return NULL;
+ }
+
+ ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma,
+ sizeof (Elf32_Ehdr), initial_bufsize);
+ if (nread <= 0)
+ {
+ read_error:
+ free (buffer);
+ __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
+ return NULL;
+ }
+
+ if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
+ {
+ bad_elf:
+ __libdwfl_seterrno (DWFL_E_BADELF);
+ return NULL;
+ }
+
+ /* Extract the information we need from the file header. */
+
+ union
+ {
+ Elf32_Ehdr e32;
+ Elf64_Ehdr e64;
+ } ehdr;
+ Elf_Data xlatefrom =
+ {
+ .d_type = ELF_T_EHDR,
+ .d_buf = buffer,
+ .d_version = EV_CURRENT,
+ };
+ Elf_Data xlateto =
+ {
+ .d_type = ELF_T_EHDR,
+ .d_buf = &ehdr,
+ .d_size = sizeof ehdr,
+ .d_version = EV_CURRENT,
+ };
+
+ GElf_Off phoff;
+ uint_fast16_t phnum;
+ uint_fast16_t phentsize;
+ GElf_Off shdrs_end;
+
+ switch (buffer[EI_CLASS])
+ {
+ case ELFCLASS32:
+ xlatefrom.d_size = sizeof (Elf32_Ehdr);
+ if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
+ {
+ libelf_error:
+ __libdwfl_seterrno (DWFL_E_LIBELF);
+ return NULL;
+ }
+ phoff = ehdr.e32.e_phoff;
+ phnum = ehdr.e32.e_phnum;
+ phentsize = ehdr.e32.e_phentsize;
+ if (phentsize != sizeof (Elf32_Phdr) || phnum == 0)
+ goto bad_elf;
+ shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
+ break;
+
+ case ELFCLASS64:
+ xlatefrom.d_size = sizeof (Elf64_Ehdr);
+ if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
+ goto libelf_error;
+ phoff = ehdr.e64.e_phoff;
+ phnum = ehdr.e64.e_phnum;
+ phentsize = ehdr.e64.e_phentsize;
+ if (phentsize != sizeof (Elf64_Phdr) || phnum == 0)
+ goto bad_elf;
+ shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
+ break;
+
+ default:
+ goto bad_elf;
+ }
+
+
+ /* The file header tells where to find the program headers.
+ These are what we use to actually choose what to read. */
+
+ xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
+ xlatefrom.d_size = phnum * phentsize;
+
+ if ((size_t) nread >= phoff + phnum * phentsize)
+ /* We already have all the phdrs from the initial read. */
+ xlatefrom.d_buf = buffer + phoff;
+ else
+ {
+ /* Read in the program headers. */
+
+ if (initial_bufsize < phnum * phentsize)
+ {
+ unsigned char *newbuf = realloc (buffer, phnum * phentsize);
+ if (newbuf == NULL)
+ {
+ free (buffer);
+ goto no_memory;
+ }
+ buffer = newbuf;
+ }
+ nread = (*read_memory) (arg, buffer, ehdr_vma + phoff,
+ phnum * phentsize, phnum * phentsize);
+ if (nread <= 0)
+ goto read_error;
+
+ xlatefrom.d_buf = buffer;
+ }
+
+ union
+ {
+ Elf32_Phdr p32[phnum];
+ Elf64_Phdr p64[phnum];
+ } phdrs;
+
+ xlateto.d_buf = &phdrs;
+ xlateto.d_size = sizeof phdrs;
+
+ /* Scan for PT_LOAD segments to find the total size of the file image. */
+ size_t contents_size = 0;
+ GElf_Off segments_end = 0;
+ GElf_Addr loadbase = ehdr_vma;
+ switch (ehdr.e32.e_ident[EI_CLASS])
+ {
+ inline void handle_segment (GElf_Addr vaddr, GElf_Off offset,
+ GElf_Xword filesz, GElf_Xword align)
+ {
+ GElf_Off segment_end = ((offset + filesz + align - 1) & -align);
+
+ if (segment_end > (GElf_Off) contents_size)
+ contents_size = segment_end;
+
+ if ((offset & -align) == 0 && loadbase == ehdr_vma)
+ loadbase = ehdr_vma - (vaddr & -align);
+
+ segments_end = offset + filesz;
+ }
+
+ case ELFCLASS32:
+ if (elf32_xlatetom (&xlateto, &xlatefrom,
+ ehdr.e32.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p32[i].p_type == PT_LOAD)
+ handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
+ phdrs.p32[i].p_filesz, phdrs.p32[i].p_align);
+ break;
+
+ case ELFCLASS64:
+ if (elf32_xlatetom (&xlateto, &xlatefrom,
+ ehdr.e32.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p32[i].p_type == PT_LOAD)
+ handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
+ phdrs.p64[i].p_filesz, phdrs.p64[i].p_align);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ /* Trim the last segment so we don't bother with zeros in the last page
+ that are off the end of the file. However, if the extra bit in that
+ page includes the section headers, keep them. */
+ if ((GElf_Off) contents_size > segments_end
+ && (GElf_Off) contents_size >= shdrs_end)
+ {
+ contents_size = segments_end;
+ if ((GElf_Off) contents_size < shdrs_end)
+ contents_size = shdrs_end;
+ }
+ else
+ contents_size = segments_end;
+
+ free (buffer);
+
+ /* Now we know the size of the whole image we want read in. */
+ buffer = calloc (1, contents_size);
+ if (buffer == NULL)
+ goto no_memory;
+
+ switch (ehdr.e32.e_ident[EI_CLASS])
+ {
+ inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
+ GElf_Xword filesz, GElf_Xword align)
+ {
+ GElf_Off start = offset & -align;
+ GElf_Off end = (offset + filesz + align - 1) & -align;
+ if (end > (GElf_Off) contents_size)
+ end = contents_size;
+ nread = (*read_memory) (arg, buffer + start,
+ (loadbase + vaddr) & -align,
+ end - start, end - start);
+ return nread <= 0;
+ }
+
+ case ELFCLASS32:
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p32[i].p_type == PT_LOAD)
+ if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
+ phdrs.p32[i].p_filesz, phdrs.p32[i].p_align))
+ goto read_error;
+
+ /* If the segments visible in memory didn't include the section
+ headers, then clear them from the file header. */
+ if (contents_size < shdrs_end)
+ {
+ ehdr.e32.e_shoff = 0;
+ ehdr.e32.e_shnum = 0;
+ ehdr.e32.e_shstrndx = 0;
+ }
+
+ /* This will normally have been in the first PT_LOAD segment. But it
+ conceivably could be missing, and we might have just changed it. */
+ xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
+ xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
+ xlatefrom.d_buf = &ehdr.e32;
+ xlateto.d_buf = buffer;
+ if (elf32_xlatetof (&xlateto, &xlatefrom,
+ ehdr.e32.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ break;
+
+ case ELFCLASS64:
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p32[i].p_type == PT_LOAD)
+ if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
+ phdrs.p64[i].p_filesz, phdrs.p64[i].p_align))
+ goto read_error;
+
+ /* If the segments visible in memory didn't include the section
+ headers, then clear them from the file header. */
+ if (contents_size < shdrs_end)
+ {
+ ehdr.e64.e_shoff = 0;
+ ehdr.e64.e_shnum = 0;
+ ehdr.e64.e_shstrndx = 0;
+ }
+
+ /* This will normally have been in the first PT_LOAD segment. But it
+ conceivably could be missing, and we might have just changed it. */
+ xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
+ xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
+ xlatefrom.d_buf = &ehdr.e64;
+ xlateto.d_buf = buffer;
+ if (elf32_xlatetof (&xlateto, &xlatefrom,
+ ehdr.e64.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ /* Now we have the image. Open libelf on it. */
+
+ Elf *elf = elf_memory ((char *) buffer, contents_size);
+ if (elf == NULL)
+ {
+ free (buffer);
+ return NULL;
+ }
+
+ elf->flags |= ELF_F_MALLOCED;
+ if (loadbasep != NULL)
+ *loadbasep = loadbase;
+ return elf;
+}
diff --git a/elfutils/libdwfl/find-debuginfo.c b/elfutils/libdwfl/find-debuginfo.c
new file mode 100644
index 00000000..03171914
--- /dev/null
+++ b/elfutils/libdwfl/find-debuginfo.c
@@ -0,0 +1,165 @@
+/* Standard find_debuginfo callback for libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "system.h"
+
+
+#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug"
+
+
+/* Try to open64 [DIR/][SUBDIR/]DEBUGLINK, return file descriptor or -1.
+ On success, *DEBUGINFO_FILE_NAME has the malloc'd name of the open file. */
+static int
+try_open (const char *dir, const char *subdir, const char *debuglink,
+ char **debuginfo_file_name)
+{
+ char *fname = NULL;
+ if (dir == NULL && subdir == NULL)
+ fname = strdup (debuglink);
+ else if (subdir == NULL)
+ asprintf (&fname, "%s/%s", dir, debuglink);
+ else if (dir == NULL)
+ asprintf (&fname, "%s/%s", subdir, debuglink);
+ else
+ asprintf (&fname, "%s/%s/%s", dir, subdir, debuglink);
+
+ if (fname == NULL)
+ return -1;
+
+ int fd = TEMP_FAILURE_RETRY (open64 (fname, O_RDONLY));
+ if (fd < 0)
+ free (fname);
+ else
+ *debuginfo_file_name = fname;
+
+ return fd;
+}
+
+/* Return true iff the FD's contents CRC matches DEBUGLINK_CRC. */
+static inline bool
+check_crc (int fd, GElf_Word debuglink_crc)
+{
+ uint32_t file_crc;
+ return (__libdwfl_crc32_file (fd, &file_crc) == 0
+ && file_crc == debuglink_crc);
+}
+
+int
+dwfl_standard_find_debuginfo (Dwfl_Module *mod,
+ void **userdata __attribute__ ((unused)),
+ const char *modname __attribute__ ((unused)),
+ GElf_Addr base __attribute__ ((unused)),
+ const char *file_name,
+ const char *debuglink_file,
+ GElf_Word debuglink_crc,
+ char **debuginfo_file_name)
+{
+ bool cancheck = debuglink_crc != (GElf_Word) 0;
+
+ const char *file_basename = file_name == NULL ? NULL : basename (file_name);
+ if (debuglink_file == NULL)
+ {
+ if (file_basename == NULL)
+ {
+ errno = 0;
+ return -1;
+ }
+
+ size_t len = strlen (file_basename);
+ char *localname = alloca (len + sizeof ".debug");
+ memcpy (localname, file_basename, len);
+ memcpy (&localname[len], ".debug", sizeof ".debug");
+ debuglink_file = localname;
+ cancheck = false;
+ }
+
+ /* Look for a file named DEBUGLINK_FILE in the directories
+ indicated by the debug directory path setting. */
+
+ const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
+ char *path = strdupa ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
+ ?: DEFAULT_DEBUGINFO_PATH);
+
+ /* A leading - or + in the whole path sets whether to check file CRCs. */
+ bool defcheck = true;
+ if (path[0] == '-' || path[0] == '+')
+ {
+ defcheck = path[0] == '+';
+ ++path;
+ }
+
+ char *file_dirname = (file_basename == file_name ? NULL
+ : strndupa (file_name, file_basename - 1 - file_name));
+ char *p;
+ while ((p = strsep (&path, ":")) != NULL)
+ {
+ /* A leading - or + says whether to check file CRCs for this element. */
+ bool check = defcheck;
+ if (*p == '+' || *p == '-')
+ check = *p++ == '+';
+ check = check && cancheck;
+
+ const char *dir, *subdir;
+ switch (p[0])
+ {
+ case '\0':
+ /* An empty entry says to try the main file's directory. */
+ dir = file_dirname;
+ subdir = NULL;
+ break;
+ case '/':
+ /* An absolute path says to look there for a subdirectory
+ named by the main file's absolute directory.
+ This cannot be applied to a relative file name. */
+ if (file_dirname == NULL || file_dirname[0] != '/')
+ continue;
+ dir = p;
+ subdir = file_dirname + 1;
+ break;
+ default:
+ /* A relative path says to try a subdirectory of that name
+ in the main file's directory. */
+ dir = file_dirname;
+ subdir = p;
+ break;
+ }
+
+ char *fname;
+ int fd = try_open (dir, subdir, debuglink_file, &fname);
+ if (fd < 0)
+ switch (errno)
+ {
+ case ENOENT:
+ case ENOTDIR:
+ continue;
+ default:
+ return -1;
+ }
+ if (!check || check_crc (fd, debuglink_crc))
+ {
+ *debuginfo_file_name = fname;
+ return fd;
+ }
+ free (fname);
+ close (fd);
+ }
+
+ /* No dice. */
+ errno = 0;
+ return -1;
+}
+INTDEF (dwfl_standard_find_debuginfo)
diff --git a/elfutils/libdwfl/libdwfl.h b/elfutils/libdwfl/libdwfl.h
new file mode 100644
index 00000000..64e38d59
--- /dev/null
+++ b/elfutils/libdwfl/libdwfl.h
@@ -0,0 +1,335 @@
+/* Interfaces for libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifndef _LIBDWFL_H
+#define _LIBDWFL_H 1
+
+#include "libdw.h"
+
+/* Handle for a session using the library. */
+typedef struct Dwfl Dwfl;
+
+/* Handle for a module. */
+typedef struct Dwfl_Module Dwfl_Module;
+
+/* Handle describing a line record. */
+typedef struct Dwfl_Line Dwfl_Line;
+
+/* Callbacks. */
+typedef struct
+{
+ int (*find_elf) (Dwfl_Module *mod, void **userdata,
+ const char *modname, Dwarf_Addr base,
+ char **file_name, Elf **elfp);
+
+ int (*find_debuginfo) (Dwfl_Module *mod, void **userdata,
+ const char *modname, Dwarf_Addr base,
+ const char *file_name,
+ const char *debuglink_file, GElf_Word debuglink_crc,
+ char **debuginfo_file_name);
+
+ /* Fill *ADDR with the loaded address of the section called SECNAME in
+ the given module. This is called exactly once for each SHF_ALLOC
+ section that relocations affecting DWARF data refer to, so it can
+ easily be used to collect state about the sections referenced. */
+ int (*section_address) (Dwfl_Module *mod, void **userdata,
+ const char *modname, Dwarf_Addr base,
+ const char *secname,
+ Elf32_Word shndx, const GElf_Shdr *shdr,
+ Dwarf_Addr *addr);
+
+ char **debuginfo_path; /* See dwfl_standard_find_debuginfo. */
+} Dwfl_Callbacks;
+
+
+/* Start a new session with the library. */
+extern Dwfl *dwfl_begin (const Dwfl_Callbacks *callbacks);
+
+/* End a session. */
+extern void dwfl_end (Dwfl *);
+
+/* Return error code of last failing function call. This value is kept
+ separately for each thread. */
+extern int dwfl_errno (void);
+
+/* Return error string for ERROR. If ERROR is zero, return error string
+ for most recent error or NULL if none occurred. If ERROR is -1 the
+ behaviour is similar to the last case except that not NULL but a legal
+ string is returned. */
+extern const char *dwfl_errmsg (int err);
+
+
+/* Start reporting the current set of modules to the library. No calls but
+ dwfl_report_* can be made on DWFL until dwfl_report_end is called. */
+extern void dwfl_report_begin (Dwfl *dwfl);
+
+/* Report that a module called NAME spans addresses [START, END).
+ Returns the module handle, either existing or newly allocated,
+ or returns a null pointer for an allocation error. */
+extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name,
+ Dwarf_Addr start, Dwarf_Addr end);
+
+/* Report a module with start and end addresses computed from the ELF
+ program headers in the given file, plus BASE. For an ET_REL file,
+ does a simple absolute section layout starting at BASE.
+ FD may be -1 to open FILE_NAME. On success, FD is consumed by the
+ library, and the `find_elf' callback will not be used for this module. */
+extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name,
+ const char *file_name, int fd,
+ GElf_Addr base);
+
+/* Similar, but report the module for offline use. All ET_EXEC files
+ being reported must be reported before any relocatable objects.
+ If this is used, dwfl_report_module and dwfl_report_elf may not be
+ used in the same reporting session. */
+extern Dwfl_Module *dwfl_report_offline (Dwfl *dwfl, const char *name,
+ const char *file_name, int fd);
+
+
+/* Finish reporting the current set of modules to the library.
+ If REMOVED is not null, it's called for each module that
+ existed before but was not included in the current report.
+ Returns a nonzero return value from the callback.
+ The callback may call dwfl_report_module; doing so with the
+ details of the module being removed prevents its removal.
+ DWFL cannot be used until this function has returned zero. */
+extern int dwfl_report_end (Dwfl *dwfl,
+ int (*removed) (Dwfl_Module *, void *,
+ const char *, Dwarf_Addr,
+ void *arg),
+ void *arg);
+
+/* Return the name of the module, and for each non-null argument store
+ interesting details: *USERDATA is a location for storing your own
+ pointer, **USERDATA is initially null; *START and *END give the address
+ range covered by the module; *DWBIAS is the address bias for debugging
+ information, and *SYMBIAS for symbol table entries (either is -1 if not
+ yet accessed); *MAINFILE is the name of the ELF file, and *DEBUGFILE the
+ name of the debuginfo file (might be equal to *MAINFILE; either is null
+ if not yet accessed). */
+extern const char *dwfl_module_info (Dwfl_Module *mod, void ***userdata,
+ Dwarf_Addr *start, Dwarf_Addr *end,
+ Dwarf_Addr *dwbias, Dwarf_Addr *symbias,
+ const char **mainfile,
+ const char **debugfile);
+
+/* Iterate through the modules, starting the walk with OFFSET == 0.
+ Calls *CALLBACK for each module as long as it returns DWARF_CB_OK.
+ When *CALLBACK returns another value, the walk stops and the
+ return value can be passed as OFFSET to resume it. Returns 0 when
+ there are no more modules, or -1 for errors. */
+extern ptrdiff_t dwfl_getmodules (Dwfl *dwfl,
+ int (*callback) (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr,
+ void *arg),
+ void *arg,
+ ptrdiff_t offset);
+
+
+/*** Standard callbacks ***/
+
+/* Standard find_debuginfo callback function.
+ This is controlled by a string specifying directories to look in.
+ If `debuginfo_path' is set in the Dwfl_Callbacks structure
+ and the char * it points to is not null, that supplies the string.
+ Otherwise a default path is used.
+
+ If the first character of the string is + or - that says to check or to
+ ignore (respectively) the CRC32 checksum from the .gnu_debuglink
+ section. The default is to check it. The remainder of the string is
+ composed of elements separated by colons. Each element can start with +
+ or - to override the global checksum behavior. If the remainder of the
+ element is empty, the directory containing the main file is tried; if
+ it's an absolute path name, the absolute directory path containing the
+ main file is taken as a subdirectory of this path; a relative path name
+ is taken as a subdirectory of the directory containing the main file.
+ Hence for /bin/ls, string ":.debug:/usr/lib/debug" says to look in /bin,
+ then /bin/.debug, then /usr/lib/debug/bin, for the file name in the
+ .gnu_debuglink section (or "ls.debug" if none was found). */
+
+extern int dwfl_standard_find_debuginfo (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr,
+ const char *, const char *,
+ GElf_Word, char **);
+
+
+/* This callback must be used when using dwfl_offline_* to report modules,
+ if ET_REL is to be supported. */
+extern int dwfl_offline_section_address (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr,
+ const char *, Elf32_Word,
+ const GElf_Shdr *,
+ Dwarf_Addr *addr);
+
+
+/* Callbacks for working with kernel modules in the running Linux kernel. */
+extern int dwfl_linux_kernel_find_elf (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr,
+ char **, Elf **);
+extern int dwfl_linux_kernel_module_section_address (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr,
+ const char *, Elf32_Word,
+ const GElf_Shdr *,
+ Dwarf_Addr *addr);
+
+/* Call dwfl_report_elf for the running Linux kernel.
+ Returns zero on success, -1 if dwfl_report_module failed,
+ or an errno code if opening the kernel binary failed. */
+extern int dwfl_linux_kernel_report_kernel (Dwfl *dwfl);
+
+/* Call dwfl_report_module for each kernel module in the running Linux kernel.
+ Returns zero on success, -1 if dwfl_report_module failed,
+ or an errno code if reading the list of modules failed. */
+extern int dwfl_linux_kernel_report_modules (Dwfl *dwfl);
+
+/* Report a kernel and its modules found on disk, for offline use.
+ If RELEASE starts with '/', it names a directory to look in;
+ if not, it names a directory to find under /lib/modules/;
+ if null, /lib/modules/`uname -r` is used.
+ Returns zero on success, -1 if dwfl_report_module failed,
+ or an errno code if finding the files on disk failed.
+
+ If PREDICATE is not null, it is called with each module to be reported;
+ its arguments are the module name, and the ELF file name or null if unknown,
+ and its return value should be zero to skip the module, one to report it,
+ or -1 to cause the call to fail and return errno. */
+extern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
+ int (*predicate) (const char *,
+ const char *));
+
+
+/* Call dwfl_report_module for each file mapped into the address space of PID.
+ Returns zero on success, -1 if dwfl_report_module failed,
+ or an errno code if opening the kernel binary failed. */
+extern int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid);
+
+/* Trivial find_elf callback for use with dwfl_linux_proc_report.
+ This uses the module name as a file name directly and tries to open it
+ if it begin with a slash, or handles the magic string "[vdso]". */
+extern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata,
+ const char *module_name, Dwarf_Addr base,
+ char **file_name, Elf **);
+
+/* Standard argument parsing for using a standard callback set. */
+struct argp;
+extern const struct argp *dwfl_standard_argp (void) __attribute__ ((const));
+
+
+/*** Relocation of addresses from Dwfl ***/
+
+/* Return the number of relocatable bases associated with the module,
+ which is zero for ET_EXEC and one for ET_DYN. Returns -1 for errors. */
+extern int dwfl_module_relocations (Dwfl_Module *mod);
+
+/* Return the relocation base index associated with the *ADDRESS location,
+ and adjust *ADDRESS to be an offset relative to that base.
+ Returns -1 for errors. */
+extern int dwfl_module_relocate_address (Dwfl_Module *mod,
+ Dwarf_Addr *address);
+
+/* Return the ELF section name for the given relocation base index;
+ if SHNDXP is not null, set *SHNDXP to the ELF section index.
+ For ET_DYN, returns "" and sets *SHNDXP to SHN_ABS; the relocation
+ base is the runtime start address reported for the module.
+ Returns null for errors. */
+extern const char *dwfl_module_relocation_info (Dwfl_Module *mod,
+ unsigned int idx,
+ Elf32_Word *shndxp);
+
+/* Validate that ADDRESS and ADDRESS+OFFSET lie in a known module
+ and both within the same contiguous region for relocation purposes.
+ Returns zero for success and -1 for errors. */
+extern int dwfl_validate_address (Dwfl *dwfl,
+ Dwarf_Addr address, Dwarf_Sword offset);
+
+
+/*** Dwarf access functions ***/
+
+/* Find the module containing the given address. */
+extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address);
+
+/* Fetch the module main ELF file (where the allocated sections
+ are found) for use with libelf. If successful, fills in *BIAS
+ with the difference between addresses within the loaded module
+ and those in symbol tables or Dwarf information referring to it. */
+extern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias);
+
+/* Fetch the module's debug information for use with libdw.
+ If successful, fills in *BIAS with the difference between
+ addresses within the loaded module and those to use with libdw. */
+extern Dwarf *dwfl_module_getdwarf (Dwfl_Module *, Dwarf_Addr *bias)
+ __nonnull_attribute__ (2);
+
+/* Get the libdw handle for each module. */
+extern ptrdiff_t dwfl_getdwarf (Dwfl *,
+ int (*callback) (Dwfl_Module *, void **,
+ const char *, Dwarf_Addr,
+ Dwarf *, Dwarf_Addr, void *),
+ void *arg, ptrdiff_t offset);
+
+/* Look up the module containing ADDR and return its debugging information,
+ loading it if necessary. */
+extern Dwarf *dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
+ __nonnull_attribute__ (3);
+
+
+/* Find the CU containing ADDR and return its DIE. */
+extern Dwarf_Die *dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
+ __nonnull_attribute__ (3);
+extern Dwarf_Die *dwfl_module_addrdie (Dwfl_Module *mod,
+ Dwarf_Addr addr, Dwarf_Addr *bias)
+ __nonnull_attribute__ (3);
+
+/* Iterate through the CUs, start with null for LASTCU. */
+extern Dwarf_Die *dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias)
+ __nonnull_attribute__ (3);
+extern Dwarf_Die *dwfl_module_nextcu (Dwfl_Module *mod,
+ Dwarf_Die *lastcu, Dwarf_Addr *bias)
+ __nonnull_attribute__ (3);
+
+/* Return the module containing the CU DIE. */
+extern Dwfl_Module *dwfl_cumodule (Dwarf_Die *cudie);
+
+
+/* Cache the source line information fo the CU and return the
+ number of Dwfl_Line entries it has. */
+extern int dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines);
+
+/* Access one line number entry within the CU. */
+extern Dwfl_Line *dwfl_onesrcline (Dwarf_Die *cudie, size_t idx);
+
+/* Get source for address. */
+extern Dwfl_Line *dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr);
+extern Dwfl_Line *dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr);
+
+/* Get address for source. */
+extern int dwfl_module_getsrc_file (Dwfl_Module *mod,
+ const char *fname, int lineno, int column,
+ Dwfl_Line ***srcsp, size_t *nsrcs);
+
+/* Return the module containing this line record. */
+extern Dwfl_Module *dwfl_linemodule (Dwfl_Line *line);
+
+/* Return the source file name and fill in other information.
+ Arguments may be null for unneeded fields. */
+extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr,
+ int *linep, int *colp,
+ Dwarf_Word *mtime, Dwarf_Word *length);
+
+
+/* Find the symbol that ADDRESS lies inside, and return its name. */
+const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address);
+
+
+
+#endif /* libdwfl.h */
diff --git a/elfutils/libdwfl/libdwflP.h b/elfutils/libdwfl/libdwflP.h
new file mode 100644
index 00000000..ae8985db
--- /dev/null
+++ b/elfutils/libdwfl/libdwflP.h
@@ -0,0 +1,254 @@
+/* Internal definitions for libdwfl.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifndef _LIBDWFLP_H
+#define _LIBDWFLP_H 1
+
+#ifndef PACKAGE
+# include <config.h>
+#endif
+#include <libdwfl.h>
+#include <libebl.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../libdw/libdwP.h" /* We need its INTDECLs. */
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("elfutils", Str)
+
+#define DWFL_ERRORS \
+ DWFL_ERROR (NOERROR, N_("no error")) \
+ DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error")) \
+ DWFL_ERROR (NOMEM, N_("out of memory")) \
+ DWFL_ERROR (ERRNO, N_("See errno")) \
+ DWFL_ERROR (LIBELF, N_("See elf_errno")) \
+ DWFL_ERROR (LIBDW, N_("See dwarf_errno")) \
+ DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)")) \
+ DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file")) \
+ DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type")) \
+ DWFL_ERROR (BADRELOFF, N_("r_offset is bogus")) \
+ DWFL_ERROR (BADSTROFF, N_("offset out of range")) \
+ DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol")) \
+ DWFL_ERROR (CB, N_("Callback returned failure")) \
+ DWFL_ERROR (NO_DWARF, N_("No DWARF information found")) \
+ DWFL_ERROR (NO_SYMTAB, N_("No symbol table found")) \
+ DWFL_ERROR (NO_PHDR, N_("No ELF program headers")) \
+ DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module")) \
+ DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range")) \
+ DWFL_ERROR (NO_MATCH, N_("no matching address range")) \
+ DWFL_ERROR (TRUNCATED, N_("image truncated")) \
+ DWFL_ERROR (BADELF, N_("not a valid ELF file"))
+
+#define DWFL_ERROR(name, text) DWFL_E_##name,
+typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
+#undef DWFL_ERROR
+
+#define OTHER_ERROR(name) ((unsigned int) DWFL_E_##name << 16)
+#define DWFL_E(name, errno) (OTHER_ERROR (name) | (errno))
+
+extern int __libdwfl_canon_error (Dwfl_Error error) internal_function;
+extern void __libdwfl_seterrno (Dwfl_Error error) internal_function;
+
+struct Dwfl
+{
+ const Dwfl_Callbacks *callbacks;
+
+ Dwfl_Module *modulelist; /* List in order used by full traversals. */
+
+ Dwfl_Module **modules;
+ size_t nmodules;
+
+ GElf_Addr offline_next_address;
+};
+
+#define OFFLINE_REDZONE 0x10000
+
+struct dwfl_file
+{
+ char *name;
+ int fd;
+
+ Elf *elf;
+ GElf_Addr bias; /* Actual load address - p_vaddr. */
+};
+
+struct Dwfl_Module
+{
+ Dwfl *dwfl;
+ struct Dwfl_Module *next; /* Link on Dwfl.modulelist. */
+
+ void *userdata;
+
+ char *name; /* Iterator name for this module. */
+ GElf_Addr low_addr, high_addr;
+
+ struct dwfl_file main, debug;
+ Ebl *ebl;
+ GElf_Half e_type; /* GElf_Ehdr.e_type cache. */
+ Dwfl_Error elferr; /* Previous failure to open main file. */
+
+ struct dwfl_relocation *reloc_info; /* Relocatable sections. */
+
+ struct dwfl_file *symfile; /* Either main or debug. */
+ Elf_Data *symdata; /* Data in the ELF symbol table section. */
+ size_t syments; /* sh_size / sh_entsize of that section. */
+ const Elf_Data *symstrdata; /* Data for its string table. */
+ Elf_Data *symxndxdata; /* Data in the extended section index table. */
+ Dwfl_Error symerr; /* Previous failure to load symbols. */
+
+ Dwarf *dw; /* libdw handle for its debugging info. */
+ Dwfl_Error dwerr; /* Previous failure to load info. */
+
+ /* Known CU's in this module. */
+ struct dwfl_cu *first_cu, **cu;
+ unsigned int ncu;
+
+ void *lazy_cu_root; /* Table indexed by Dwarf_Off of CU. */
+ unsigned int lazycu; /* Possible users, deleted when none left. */
+
+ struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs. */
+ unsigned int naranges;
+
+ bool gc; /* Mark/sweep flag. */
+};
+
+
+
+/* Information cached about each CU in Dwfl_Module.dw. */
+struct dwfl_cu
+{
+ /* This caches libdw information about the CU. It's also the
+ address passed back to users, so we take advantage of the
+ fact that it's placed first to cast back. */
+ Dwarf_Die die;
+
+ Dwfl_Module *mod; /* Pointer back to containing module. */
+
+ struct dwfl_cu *next; /* CU immediately following in the file. */
+
+ struct Dwfl_Lines *lines;
+};
+
+struct Dwfl_Lines
+{
+ struct dwfl_cu *cu;
+
+ /* This is what the opaque Dwfl_Line * pointers we pass to users are.
+ We need to recover pointers to our struct dwfl_cu and a record in
+ libdw's Dwarf_Line table. To minimize the memory used in addition
+ to libdw's Dwarf_Lines buffer, we just point to our own index in
+ this table, and have one pointer back to the CU. The indices here
+ match those in libdw's Dwarf_CU.lines->info table. */
+ struct Dwfl_Line
+ {
+ unsigned int idx; /* My index in the dwfl_cu.lines table. */
+ } idx[0];
+};
+
+static inline struct dwfl_cu *
+dwfl_linecu (const Dwfl_Line *line)
+{
+ const struct Dwfl_Lines *lines = ((const void *) line
+ - offsetof (struct Dwfl_Lines,
+ idx[line->idx]));
+ return lines->cu;
+}
+
+/* This describes a contiguous address range that lies in a single CU.
+ We condense runs of Dwarf_Arange entries for the same CU into this. */
+struct dwfl_arange
+{
+ struct dwfl_cu *cu;
+ size_t arange; /* Index in Dwarf_Aranges. */
+};
+
+
+
+
+extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function;
+
+
+/* Process relocations in debugging sections in an ET_REL file.
+ DEBUGFILE 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 DEBUGFILE will read the relocated data. */
+extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile)
+ internal_function;
+
+/* Adjust *VALUE from section-relative to absolute.
+ MOD->dwfl->callbacks->section_address is called to determine the actual
+ address of a loaded section. */
+extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod,
+ size_t m_shstrndx,
+ Elf32_Word shndx,
+ GElf_Addr *value)
+ internal_function;
+
+/* Iterate through all the CU's in the module. Start by passing a null
+ LASTCU, and then pass the last *CU returned. Success return with null
+ *CU no more CUs. */
+extern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
+ struct dwfl_cu **cu) internal_function;
+
+/* Find the CU by address. */
+extern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr,
+ struct dwfl_cu **cu) internal_function;
+
+/* Ensure that CU->lines (and CU->cu->lines) is set up. */
+extern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu)
+ internal_function;
+
+
+extern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len)
+ attribute_hidden;
+extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden;
+
+
+
+/* Avoid PLT entries. */
+INTDECL (dwfl_begin)
+INTDECL (dwfl_errmsg)
+INTDECL (dwfl_addrmodule)
+INTDECL (dwfl_addrdwarf)
+INTDECL (dwfl_addrdie)
+INTDECL (dwfl_module_addrdie)
+INTDECL (dwfl_module_getdwarf)
+INTDECL (dwfl_module_getelf)
+INTDECL (dwfl_module_getsrc)
+INTDECL (dwfl_report_elf)
+INTDECL (dwfl_report_begin)
+INTDECL (dwfl_report_module)
+INTDECL (dwfl_report_offline)
+INTDECL (dwfl_report_end)
+INTDECL (dwfl_standard_find_debuginfo)
+INTDECL (dwfl_linux_kernel_find_elf)
+INTDECL (dwfl_linux_kernel_module_section_address)
+INTDECL (dwfl_linux_proc_report)
+INTDECL (dwfl_linux_proc_find_elf)
+INTDECL (dwfl_linux_kernel_report_kernel)
+INTDECL (dwfl_linux_kernel_report_modules)
+INTDECL (dwfl_linux_kernel_report_offline)
+INTDECL (dwfl_offline_section_address)
+INTDECL (dwfl_module_relocate_address)
+
+/* Leading arguments standard to callbacks passed a Dwfl_Module. */
+#define MODCB_ARGS(mod) (mod), &(mod)->userdata, (mod)->name, (mod)->low_addr
+#define CBFAIL (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB);
+
+
+#endif /* libdwflP.h */
diff --git a/elfutils/libdwfl/libdwfl_crc32.c b/elfutils/libdwfl/libdwfl_crc32.c
new file mode 100644
index 00000000..4a6cea74
--- /dev/null
+++ b/elfutils/libdwfl/libdwfl_crc32.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32 attribute_hidden __libdwfl_crc32
+#define LIB_SYSTEM_H 1
+#include <libdwflP.h>
+#include "../lib/crc32.c"
diff --git a/elfutils/libdwfl/libdwfl_crc32_file.c b/elfutils/libdwfl/libdwfl_crc32_file.c
new file mode 100644
index 00000000..a7915083
--- /dev/null
+++ b/elfutils/libdwfl/libdwfl_crc32_file.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32_file attribute_hidden __libdwfl_crc32_file
+#define crc32 __libdwfl_crc32
+#define LIB_SYSTEM_H 1
+#include <libdwflP.h>
+#include "../lib/crc32_file.c"
diff --git a/elfutils/libdwfl/lines.c b/elfutils/libdwfl/lines.c
new file mode 100644
index 00000000..d48b3803
--- /dev/null
+++ b/elfutils/libdwfl/lines.c
@@ -0,0 +1,37 @@
+/* Fetch source line info for CU.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+Dwfl_Error
+internal_function_def
+__libdwfl_cu_getsrclines (struct dwfl_cu *cu)
+{
+ if (cu->lines == NULL)
+ {
+ Dwarf_Lines *lines;
+ size_t nlines;
+ if (INTUSE(dwarf_getsrclines) (&cu->die, &lines, &nlines) != 0)
+ return DWFL_E_LIBDW;
+
+ cu->lines = malloc (offsetof (struct Dwfl_Lines, idx[nlines]));
+ if (cu->lines == NULL)
+ return DWFL_E_NOMEM;
+ cu->lines->cu = cu;
+ for (unsigned int i = 0; i < nlines; ++i)
+ cu->lines->idx[i].idx = i;
+ }
+
+ return DWFL_E_NOERROR;
+}
diff --git a/elfutils/libdwfl/linux-kernel-modules.c b/elfutils/libdwfl/linux-kernel-modules.c
new file mode 100644
index 00000000..ba65c599
--- /dev/null
+++ b/elfutils/libdwfl/linux-kernel-modules.c
@@ -0,0 +1,442 @@
+/* Standard libdwfl callbacks for debugging the running Linux kernel.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include <config.h>
+#undef _FILE_OFFSET_BITS /* Doesn't jibe with fts. */
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/utsname.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <fts.h>
+
+
+#define MODULEDIRFMT "/lib/modules/%s"
+
+#define MODULELIST "/proc/modules"
+#define SECADDRFMT "/sys/module/%s/sections/%s"
+
+
+/* Try to open the given file as it is or under the debuginfo directory. */
+static int
+try_kernel_name (Dwfl *dwfl, char **fname)
+{
+ if (*fname == NULL)
+ return -1;
+
+ int fd = TEMP_FAILURE_RETRY (open64 (*fname, O_RDONLY));
+ if (fd < 0)
+ {
+ char *debugfname = NULL;
+ Dwfl_Module fakemod = { .dwfl = dwfl };
+ fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
+ *fname, basename (*fname), 0,
+ &debugfname);
+ free (*fname);
+ *fname = debugfname;
+ }
+
+ return fd;
+}
+
+static inline const char *
+kernel_release (void)
+{
+ /* Cache the `uname -r` string we'll use. */
+ static struct utsname utsname;
+ if (utsname.release[0] == '\0' && uname (&utsname) != 0)
+ return NULL;
+ return utsname.release;
+}
+
+static int
+report_kernel (Dwfl *dwfl, const char *release,
+ int (*predicate) (const char *module, const char *file))
+{
+ if (dwfl == NULL)
+ return -1;
+
+ char *fname = NULL;
+ if (release[0] == '/')
+ asprintf (&fname, "%s/vmlinux", release);
+ else
+ asprintf (&fname, "/boot/vmlinux-%s", release);
+ int fd = try_kernel_name (dwfl, &fname);
+ if (fd < 0 && release[0] != '/')
+ {
+ free (fname);
+ fname = NULL;
+ asprintf (&fname, MODULEDIRFMT "/vmlinux", release);
+ fd = try_kernel_name (dwfl, &fname);
+ }
+
+ int result = 0;
+ if (fd < 0)
+ result = (predicate != NULL && !(*predicate) ("kernel", NULL)) ? 0 : errno;
+ else
+ {
+ bool report = true;
+
+ if (predicate != NULL)
+ {
+ /* Let the predicate decide whether to use this one. */
+ int want = (*predicate) ("kernel", fname);
+ if (want < 0)
+ result = errno;
+ report = want > 0;
+ }
+
+ if (report
+ && INTUSE(dwfl_report_elf) (dwfl, "kernel", fname, fd, 0) == NULL)
+ {
+ close (fd);
+ result = -1;
+ }
+ }
+
+ free (fname);
+
+ return result;
+}
+
+/* Report a kernel and all its modules found on disk, for offline use.
+ If RELEASE starts with '/', it names a directory to look in;
+ if not, it names a directory to find under /lib/modules/;
+ if null, /lib/modules/`uname -r` is used.
+ Returns zero on success, -1 if dwfl_report_module failed,
+ or an errno code if finding the files on disk failed. */
+int
+dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
+ int (*predicate) (const char *module,
+ const char *file))
+{
+ if (release == NULL)
+ {
+ release = kernel_release ();
+ if (release == NULL)
+ return errno;
+ }
+
+ /* First report the kernel. */
+ int result = report_kernel (dwfl, release, predicate);
+ if (result == 0)
+ {
+ /* Do "find /lib/modules/RELEASE/kernel -name *.ko". */
+
+ char *modulesdir[] = { NULL, NULL };
+ if (release[0] == '/')
+ modulesdir[0] = (char *) release;
+ else
+ {
+ asprintf (&modulesdir[0], MODULEDIRFMT "/kernel", release);
+ if (modulesdir[0] == NULL)
+ return errno;
+ }
+
+ FTS *fts = fts_open (modulesdir, FTS_LOGICAL | FTS_NOSTAT, NULL);
+ if (modulesdir[0] == (char *) release)
+ modulesdir[0] = NULL;
+ if (fts == NULL)
+ {
+ free (modulesdir[0]);
+ return errno;
+ }
+
+ FTSENT *f;
+ while ((f = fts_read (fts)) != NULL)
+ {
+ switch (f->fts_info)
+ {
+ case FTS_F:
+ case FTS_NSOK:
+ /* See if this file name matches "*.ko". */
+ if (f->fts_namelen > 3
+ && !memcmp (f->fts_name + f->fts_namelen - 3, ".ko", 4))
+ {
+ /* We have a .ko file to report. Following the algorithm
+ by which the kernel makefiles set KBUILD_MODNAME, we
+ replace all ',' or '-' with '_' in the file name and
+ call that the module name. Modules could well be
+ built using different embedded names than their file
+ names. To handle that, we would have to look at the
+ __this_module.name contents in the module's text. */
+
+ char name[f->fts_namelen - 3 + 1];
+ for (size_t i = 0; i < f->fts_namelen - 3U; ++i)
+ if (f->fts_name[i] == '-' || f->fts_name[i] == ',')
+ name[i] = '_';
+ else
+ name[i] = f->fts_name[i];
+ name[f->fts_namelen - 3] = '\0';
+
+ if (predicate != NULL)
+ {
+ /* Let the predicate decide whether to use this one. */
+ int want = (*predicate) (name, f->fts_path);
+ if (want < 0)
+ {
+ result = -1;
+ break;
+ }
+ if (!want)
+ continue;
+ }
+
+ if (dwfl_report_offline (dwfl, name,
+ f->fts_path, -1) == NULL)
+ {
+ result = -1;
+ break;
+ }
+ }
+ continue;
+
+ case FTS_ERR:
+ case FTS_DNR:
+ case FTS_NS:
+ result = f->fts_errno;
+ break;
+
+ default:
+ continue;
+ }
+
+ /* We only get here in error cases. */
+ break;
+ }
+ fts_close (fts);
+ free (modulesdir[0]);
+ }
+
+ return result;
+}
+INTDEF (dwfl_linux_kernel_report_offline)
+
+
+/* Find the ELF file for the running kernel and dwfl_report_elf it. */
+int
+dwfl_linux_kernel_report_kernel (Dwfl *dwfl)
+{
+ const char *release = kernel_release ();
+ if (release == NULL)
+ return errno;
+
+ return report_kernel (dwfl, release, NULL);
+}
+INTDEF (dwfl_linux_kernel_report_kernel)
+
+
+/* Dwfl_Callbacks.find_elf for the running Linux kernel and its modules. */
+
+int
+dwfl_linux_kernel_find_elf (Dwfl_Module *mod __attribute__ ((unused)),
+ void **userdata __attribute__ ((unused)),
+ const char *module_name,
+ Dwarf_Addr base __attribute__ ((unused)),
+ char **file_name,
+ Elf **elfp __attribute__ ((unused)))
+{
+ const char *release = kernel_release ();
+ if (release == NULL)
+ return errno;
+
+ /* Do "find /lib/modules/`uname -r`/kernel -name MODULE_NAME.ko". */
+
+ char *modulesdir[] = { NULL, NULL };
+ asprintf (&modulesdir[0], MODULEDIRFMT "/kernel", release);
+ if (modulesdir[0] == NULL)
+ return -1;
+
+ FTS *fts = fts_open (modulesdir, FTS_LOGICAL | FTS_NOSTAT, NULL);
+ if (fts == NULL)
+ {
+ free (modulesdir[0]);
+ return -1;
+ }
+
+ size_t namelen = strlen (module_name);
+
+ /* This is a kludge. There is no actual necessary relationship between
+ the name of the .ko file installed and the module name the kernel
+ knows it by when it's loaded. The kernel's only idea of the module
+ name comes from the name embedded in the object's magic
+ .gnu.linkonce.this_module section.
+
+ In practice, these module names match the .ko file names except for
+ some using '_' and some using '-'. So our cheap kludge is to look for
+ two files when either a '_' or '-' appears in a module name, one using
+ only '_' and one only using '-'. */
+
+ char alternate_name[namelen + 1];
+ inline bool subst_name (char from, char to)
+ {
+ const char *n = memchr (module_name, from, namelen);
+ if (n == NULL)
+ return false;
+ char *a = mempcpy (alternate_name, module_name, n - module_name);
+ *a++ = to;
+ ++n;
+ const char *p;
+ while ((p = memchr (n, from, namelen - (n - module_name))) != NULL)
+ {
+ a = mempcpy (a, n, p - n);
+ *a++ = to;
+ n = p + 1;
+ }
+ memcpy (a, n, namelen - (n - module_name) + 1);
+ return true;
+ }
+ if (!subst_name ('-', '_') && !subst_name ('_', '-'))
+ alternate_name[0] = '\0';
+
+ FTSENT *f;
+ int error = ENOENT;
+ while ((f = fts_read (fts)) != NULL)
+ {
+ error = ENOENT;
+ switch (f->fts_info)
+ {
+ case FTS_F:
+ case FTS_NSOK:
+ /* See if this file name is "MODULE_NAME.ko". */
+ if (f->fts_namelen == namelen + 3
+ && !memcmp (f->fts_name + namelen, ".ko", 4)
+ && (!memcmp (f->fts_name, module_name, namelen)
+ || !memcmp (f->fts_name, alternate_name, namelen)))
+ {
+ int fd = open64 (f->fts_accpath, O_RDONLY);
+ *file_name = strdup (f->fts_path);
+ fts_close (fts);
+ free (modulesdir[0]);
+ if (fd < 0)
+ free (*file_name);
+ else if (*file_name == NULL)
+ {
+ close (fd);
+ fd = -1;
+ }
+ return fd;
+ }
+ break;
+
+ case FTS_ERR:
+ case FTS_DNR:
+ case FTS_NS:
+ error = f->fts_errno;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ fts_close (fts);
+ free (modulesdir[0]);
+ errno = error;
+ return -1;
+}
+INTDEF (dwfl_linux_kernel_find_elf)
+
+
+/* Dwfl_Callbacks.section_address for kernel modules in the running Linux.
+ We read the information from /sys/module directly. */
+
+int
+dwfl_linux_kernel_module_section_address
+(Dwfl_Module *mod __attribute__ ((unused)),
+ void **userdata __attribute__ ((unused)),
+ const char *modname, Dwarf_Addr base __attribute__ ((unused)),
+ const char *secname, Elf32_Word shndx __attribute__ ((unused)),
+ const GElf_Shdr *shdr __attribute__ ((unused)),
+ Dwarf_Addr *addr)
+{
+ char *sysfile = NULL;
+ asprintf (&sysfile, SECADDRFMT, modname, secname);
+ if (sysfile == NULL)
+ return ENOMEM;
+
+ FILE *f = fopen (sysfile, "r");
+ if (f == NULL)
+ {
+ if (errno == ENOENT)
+ {
+ /* The .modinfo and .data.percpu sections are never kept
+ loaded in the kernel. If the kernel was compiled without
+ CONFIG_MODULE_UNLOAD, the .exit.* sections are not
+ actually loaded at all.
+
+ Just relocate these bogusly to zero. This part of the
+ debug information will not be of any use. */
+
+ if (!strcmp (secname, ".modinfo")
+ || !strcmp (secname, ".data.percpu")
+ || !strncmp (secname, ".exit", 5))
+ {
+ *addr = 0;
+ return DWARF_CB_OK;
+ }
+ }
+
+ return DWARF_CB_ABORT;
+ }
+
+ (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
+
+ int result = (fscanf (f, "%" PRIi64 "\n", addr) == 1 ? 0
+ : ferror_unlocked (f) ? errno : ENOEXEC);
+ fclose (f);
+
+ if (result == 0)
+ return DWARF_CB_OK;
+
+ errno = result;
+ return DWARF_CB_ABORT;
+}
+INTDEF (dwfl_linux_kernel_module_section_address)
+
+int
+dwfl_linux_kernel_report_modules (Dwfl *dwfl)
+{
+ FILE *f = fopen (MODULELIST, "r");
+ if (f == NULL)
+ return errno;
+
+ (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
+
+ int result = 0;
+ Dwarf_Addr modaddr;
+ unsigned long int modsz;
+ char modname[128];
+ while (fscanf (f, "%128s %lu %*s %*s %*s %" PRIi64 "\n",
+ modname, &modsz, &modaddr) == 3)
+ if (INTUSE(dwfl_report_module) (dwfl, modname,
+ modaddr, modaddr + modsz) == NULL)
+ {
+ result = -1;
+ break;
+ }
+
+ if (result == 0)
+ result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
+
+ fclose (f);
+
+ return result;
+}
+INTDEF (dwfl_linux_kernel_report_modules)
diff --git a/elfutils/libdwfl/linux-proc-maps.c b/elfutils/libdwfl/linux-proc-maps.c
new file mode 100644
index 00000000..2611c73a
--- /dev/null
+++ b/elfutils/libdwfl/linux-proc-maps.c
@@ -0,0 +1,285 @@
+/* Standard libdwfl callbacks for debugging a live Linux process.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <endian.h>
+
+
+#define PROCMAPSFMT "/proc/%d/maps"
+#define PROCMEMFMT "/proc/%d/mem"
+#define PROCAUXVFMT "/proc/%d/auxv"
+
+
+/* Search /proc/PID/auxv for the AT_SYSINFO_EHDR tag. */
+
+static int
+find_sysinfo_ehdr (pid_t pid, GElf_Addr *sysinfo_ehdr)
+{
+ char *fname = NULL;
+ asprintf (&fname, PROCAUXVFMT, pid);
+ if (fname == NULL)
+ return ENOMEM;
+
+ int fd = open64 (fname, O_RDONLY);
+ free (fname);
+ if (fd < 0)
+ return errno == ENOENT ? 0 : errno;
+
+ ssize_t nread;
+ do
+ {
+ union
+ {
+ char buffer[sizeof (long int) * 2 * 64];
+ Elf64_auxv_t a64[sizeof (long int) * 2 * 64 / sizeof (Elf64_auxv_t)];
+ Elf32_auxv_t a32[sizeof (long int) * 2 * 32 / sizeof (Elf32_auxv_t)];
+ } d;
+ nread = read (fd, &d, sizeof d);
+ if (nread > 0)
+ {
+ switch (sizeof (long int))
+ {
+ case 4:
+ for (size_t i = 0; (char *) &d.a32[i] < &d.buffer[nread]; ++i)
+ if (d.a32[i].a_type == AT_SYSINFO_EHDR)
+ {
+ *sysinfo_ehdr = d.a32[i].a_un.a_val;
+ nread = 0;
+ break;
+ }
+ break;
+ case 8:
+ for (size_t i = 0; (char *) &d.a64[i] < &d.buffer[nread]; ++i)
+ if (d.a64[i].a_type == AT_SYSINFO_EHDR)
+ {
+ *sysinfo_ehdr = d.a64[i].a_un.a_val;
+ nread = 0;
+ break;
+ }
+ break;
+ default:
+ abort ();
+ break;
+ }
+ }
+ }
+ while (nread > 0);
+
+ close (fd);
+
+ return nread < 0 ? errno : 0;
+}
+
+int
+dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid)
+{
+ if (dwfl == NULL)
+ return -1;
+
+ /* We'll notice the AT_SYSINFO_EHDR address specially when we hit it. */
+ GElf_Addr sysinfo_ehdr = 0;
+ int result = find_sysinfo_ehdr (pid, &sysinfo_ehdr);
+ if (result != 0)
+ return result;
+
+ char *fname = NULL;
+ asprintf (&fname, PROCMAPSFMT, pid);
+ if (fname == NULL)
+ return ENOMEM;
+
+ FILE *f = fopen (fname, "r");
+ free (fname);
+ if (f == NULL)
+ return errno;
+
+ (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
+
+ unsigned int last_dmajor = -1, last_dminor = -1;
+ uint64_t last_ino = -1;
+ char *last_file = NULL;
+ Dwarf_Addr low = 0, high = 0;
+
+ inline bool report (void)
+ {
+ if (last_file != NULL)
+ {
+ if (INTUSE(dwfl_report_module) (dwfl, last_file, low, high) == NULL)
+ {
+ free (last_file);
+ return true;
+ }
+ last_file = NULL;
+ }
+ return false;
+ }
+
+ char *line = NULL;
+ size_t linesz;
+ ssize_t len;
+ while ((len = getline (&line, &linesz, f)) > 0)
+ {
+ if (line[len - 1] == '\n')
+ line[len - 1] = '\0';
+
+ Dwarf_Addr start, end, offset;
+ unsigned int dmajor, dminor;
+ uint64_t ino;
+ int nread = -1;
+ if (sscanf (line, "%" PRIx64 "-%" PRIx64 " %*s %" PRIx64
+ " %x:%x %" PRIi64 " %n",
+ &start, &end, &offset, &dmajor, &dminor, &ino, &nread) < 6
+ || nread <= 0)
+ {
+ free (line);
+ return ENOEXEC;
+ }
+
+ /* If this is the special mapping AT_SYSINFO_EHDR pointed us at,
+ report the last one and then this special one. */
+ if (start == sysinfo_ehdr && start != 0)
+ {
+ if (report ())
+ {
+ bad_report:
+ free (line);
+ fclose (f);
+ return -1;
+ }
+
+ low = start;
+ high = end;
+ if (asprintf (&last_file, "[vdso: %d]", (int) pid) < 0
+ || report ())
+ goto bad_report;
+ }
+
+ char *file = line + nread + strspn (line + nread, " \t");
+ if (file[0] == '\0' || (ino == 0 && dmajor == 0 && dminor == 0))
+ /* This line doesn't indicate a file mapping. */
+ continue;
+
+ if (last_file != NULL
+ && ino == last_ino && dmajor == last_dmajor && dminor == last_dminor)
+ {
+ /* This is another portion of the same file's mapping. */
+ assert (!strcmp (last_file, file));
+ high = end;
+ }
+ else
+ {
+ /* This is a different file mapping. Report the last one. */
+ if (report ())
+ goto bad_report;
+ low = start;
+ high = end;
+ last_file = strdup (file);
+ last_ino = ino;
+ last_dmajor = dmajor;
+ last_dminor = dminor;
+ }
+ }
+ free (line);
+
+ result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
+ fclose (f);
+
+ /* Report the final one. */
+ bool lose = report ();
+
+ return result != 0 ? result : lose ? -1 : 0;
+}
+INTDEF (dwfl_linux_proc_report)
+
+
+static ssize_t
+read_proc_memory (void *arg, void *data, GElf_Addr address,
+ size_t minread, size_t maxread)
+{
+ const int fd = *(const int *) arg;
+ ssize_t nread = pread64 (fd, data, maxread, (off64_t) address);
+ if (nread > 0 && (size_t) nread < minread)
+ nread = 0;
+ return nread;
+}
+
+extern Elf *elf_from_remote_memory (GElf_Addr ehdr_vma,
+ GElf_Addr *loadbasep,
+ ssize_t (*read_memory) (void *arg,
+ void *data,
+ GElf_Addr address,
+ size_t minread,
+ size_t maxread),
+ void *arg);
+
+
+/* Dwfl_Callbacks.find_elf */
+
+int
+dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)),
+ void **userdata __attribute__ ((unused)),
+ const char *module_name, Dwarf_Addr base,
+ char **file_name, Elf **elfp)
+{
+ if (module_name[0] == '/')
+ {
+ int fd = open64 (module_name, O_RDONLY);
+ if (fd >= 0)
+ {
+ *file_name = strdup (module_name);
+ if (*file_name == NULL)
+ {
+ close (fd);
+ return ENOMEM;
+ }
+ }
+ return fd;
+ }
+
+ int pid;
+ if (sscanf (module_name, "[vdso: %d]", &pid) == 1)
+ {
+ /* Special case for in-memory ELF image. */
+
+ char *fname = NULL;
+ asprintf (&fname, PROCMEMFMT, pid);
+ if (fname == NULL)
+ return -1;
+
+ int fd = open64 (fname, O_RDONLY);
+ free (fname);
+ if (fd < 0)
+ return -1;
+
+ *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, &fd);
+
+ close (fd);
+
+ *file_name = NULL;
+ return -1;
+ }
+
+ abort ();
+ return -1;
+}
+INTDEF (dwfl_linux_proc_find_elf)
diff --git a/elfutils/libdwfl/offline.c b/elfutils/libdwfl/offline.c
new file mode 100644
index 00000000..05496399
--- /dev/null
+++ b/elfutils/libdwfl/offline.c
@@ -0,0 +1,78 @@
+/* Recover relocatibility for addresses computed from debug information.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+#include <unistd.h>
+
+/* Since dwfl_report_elf lays out the sections already, this will only be
+ called when the section headers of the debuginfo file are being
+ consulted instead. With binutils strip-to-debug, the symbol table
+ is in the debuginfo file and relocation looks there. */
+int
+dwfl_offline_section_address (Dwfl_Module *mod,
+ void **userdata __attribute__ ((unused)),
+ const char *modname __attribute__ ((unused)),
+ Dwarf_Addr base __attribute__ ((unused)),
+ const char *secname __attribute__ ((unused)),
+ Elf32_Word shndx,
+ const GElf_Shdr *shdr __attribute__ ((unused)),
+ Dwarf_Addr *addr)
+{
+ assert (mod->symfile != &mod->main);
+
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *main_shdr = gelf_getshdr (elf_getscn (mod->main.elf, shndx),
+ &shdr_mem);
+ if (unlikely (main_shdr == NULL))
+ return -1;
+
+ assert (shdr->sh_addr == 0);
+ assert (shdr->sh_flags & SHF_ALLOC);
+ assert (main_shdr->sh_addr != 0);
+ assert (main_shdr->sh_flags == shdr->sh_flags);
+
+ *addr = main_shdr->sh_addr;
+ return 0;
+}
+INTDEF (dwfl_offline_section_address)
+
+Dwfl_Module *
+dwfl_report_offline (Dwfl *dwfl, const char *name,
+ const char *file_name, int fd)
+{
+ if (dwfl == NULL)
+ return NULL;
+
+ Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, name, file_name, fd,
+ dwfl->offline_next_address);
+ if (mod != NULL)
+ {
+ /* If this is an ET_EXEC file with fixed addresses, the address range
+ it consumed may or may not intersect with the arbitrary range we
+ will use for relocatable modules. Make sure we always use a free
+ range for the offline allocations. */
+ if (dwfl->offline_next_address >= mod->low_addr
+ && dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE)
+ dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE;
+
+ /* Don't keep the file descriptor around. */
+ if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
+ {
+ close (mod->main.fd);
+ mod->main.fd = -1;
+ }
+ }
+
+ return mod;
+}
+INTDEF (dwfl_report_offline)
diff --git a/elfutils/libdwfl/relocate.c b/elfutils/libdwfl/relocate.c
new file mode 100644
index 00000000..fe03d397
--- /dev/null
+++ b/elfutils/libdwfl/relocate.c
@@ -0,0 +1,294 @@
+/* Relocate debug information.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include "libdwflP.h"
+
+typedef uint8_t GElf_Byte;
+
+/* Adjust *VALUE to add the load address of the SHNDX section.
+ We update the section header in place to cache the result. */
+
+Dwfl_Error
+internal_function_def
+__libdwfl_relocate_value (Dwfl_Module *mod, size_t symshstrndx,
+ Elf32_Word shndx, GElf_Addr *value)
+{
+ Elf_Scn *refscn = elf_getscn (mod->symfile->elf, shndx);
+ GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
+ if (refshdr == NULL)
+ return DWFL_E_LIBELF;
+
+ if ((refshdr->sh_flags & SHF_ALLOC) && refshdr->sh_addr == 0)
+ {
+ /* This is a loaded section. Find its actual
+ address and update the section header. */
+ const char *name = elf_strptr (mod->symfile->elf, symshstrndx,
+ refshdr->sh_name);
+ if (name == NULL)
+ return DWFL_E_LIBELF;
+
+ if ((*mod->dwfl->callbacks->section_address) (MODCB_ARGS (mod),
+ name, shndx, refshdr,
+ &refshdr->sh_addr))
+ return CBFAIL;
+
+ if (refshdr->sh_addr == 0)
+ /* The callback resolved this to zero, indicating it wasn't
+ really loaded but we don't really care. Mark it so we
+ don't check it again for the next relocation. */
+ refshdr->sh_flags &= ~SHF_ALLOC;
+
+ /* Update the in-core file's section header to show the final
+ load address (or unloadedness). This serves as a cache,
+ so we won't get here again for the same section. */
+ if (! gelf_update_shdr (refscn, refshdr))
+ return DWFL_E_LIBELF;
+ }
+
+ /* Apply the adjustment. */
+ *value += refshdr->sh_addr;
+ return DWFL_E_NOERROR;
+}
+
+Dwfl_Error
+internal_function_def
+__libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile)
+{
+ assert (mod->e_type == ET_REL);
+
+ GElf_Ehdr ehdr_mem;
+ const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem);
+ if (ehdr == NULL)
+ return DWFL_E_LIBELF;
+
+ size_t symshstrndx, d_shstrndx;
+ if (elf_getshstrndx (mod->symfile->elf, &symshstrndx) < 0)
+ return DWFL_E_LIBELF;
+ if (mod->symfile->elf == debugfile)
+ d_shstrndx = symshstrndx;
+ else if (elf_getshstrndx (debugfile, &d_shstrndx) < 0)
+ return DWFL_E_LIBELF;
+
+ /* Look at each section in the debuginfo file, and process the
+ relocation sections for debugging sections. */
+ Dwfl_Error result = DWFL_E_NO_DWARF;
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (debugfile, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+ if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+ {
+ /* It's a relocation section. First, fetch the name of the
+ section these relocations apply to. */
+
+ Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info);
+ if (tscn == NULL)
+ return DWFL_E_LIBELF;
+
+ GElf_Shdr tshdr_mem;
+ GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
+ const char *tname = elf_strptr (debugfile, d_shstrndx,
+ tshdr->sh_name);
+ if (tname == NULL)
+ return DWFL_E_LIBELF;
+
+ if (! ebl_debugscn_p (mod->ebl, tname))
+ /* This relocation section is not for a debugging section.
+ Nothing to do here. */
+ continue;
+
+ /* Fetch the section data that needs the relocations applied. */
+ Elf_Data *tdata = elf_rawdata (tscn, NULL);
+ if (tdata == NULL)
+ return DWFL_E_LIBELF;
+
+ /* Apply one relocation. Returns true for any invalid data. */
+ Dwfl_Error relocate (GElf_Addr offset, const GElf_Sxword *addend,
+ int rtype, int symndx)
+ {
+ /* First, resolve the symbol to an absolute value. */
+ GElf_Addr value;
+ inline Dwfl_Error adjust (GElf_Word shndx)
+ {
+ return __libdwfl_relocate_value (mod, symshstrndx,
+ shndx, &value);
+ }
+
+ if (symndx == STN_UNDEF)
+ /* When strip removes a section symbol referring to a
+ section moved into the debuginfo file, it replaces
+ that symbol index in relocs with STN_UNDEF. We
+ don't actually need the symbol, because those relocs
+ are always references relative to the nonallocated
+ debugging sections, which start at zero. */
+ value = 0;
+ else
+ {
+ GElf_Sym sym_mem;
+ GElf_Word shndx;
+ GElf_Sym *sym = gelf_getsymshndx (mod->symdata,
+ mod->symxndxdata,
+ symndx, &sym_mem,
+ &shndx);
+ if (sym == NULL)
+ return DWFL_E_LIBELF;
+
+ value = sym->st_value;
+ if (sym->st_shndx != SHN_XINDEX)
+ shndx = sym->st_shndx;
+ switch (shndx)
+ {
+ case SHN_ABS:
+ break;
+
+ case SHN_UNDEF:
+ case SHN_COMMON:
+ return DWFL_E_RELUNDEF;
+
+ default:
+ {
+ Dwfl_Error error = adjust (shndx);
+ if (error != DWFL_E_NOERROR)
+ return error;
+ break;
+ }
+ }
+ }
+
+ /* These are the types we can relocate. */
+#define TYPES DO_TYPE (BYTE, Byte) DO_TYPE (HALF, Half) \
+ DO_TYPE (WORD, Word) DO_TYPE (SWORD, Sword) \
+ DO_TYPE (XWORD, Xword) DO_TYPE (SXWORD, Sxword)
+ size_t size;
+ Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
+ switch (type)
+ {
+#define DO_TYPE(NAME, Name) \
+ case ELF_T_##NAME: \
+ size = sizeof (GElf_##Name); \
+ break;
+ TYPES
+#undef DO_TYPE
+ default:
+ return DWFL_E_BADRELTYPE;
+ }
+
+ if (offset + size >= tdata->d_size)
+ return DWFL_E_BADRELOFF;
+
+#define DO_TYPE(NAME, Name) GElf_##Name Name;
+ union { TYPES } tmpbuf;
+#undef DO_TYPE
+ Elf_Data tmpdata =
+ {
+ .d_type = type,
+ .d_buf = &tmpbuf,
+ .d_size = size,
+ .d_version = EV_CURRENT,
+ };
+ Elf_Data rdata =
+ {
+ .d_type = type,
+ .d_buf = tdata->d_buf + offset,
+ .d_size = size,
+ .d_version = EV_CURRENT,
+ };
+
+ /* XXX check for overflow? */
+ if (addend)
+ {
+ /* For the addend form, we have the value already. */
+ value += *addend;
+ switch (type)
+ {
+#define DO_TYPE(NAME, Name) \
+ case ELF_T_##NAME: \
+ tmpbuf.Name = value; \
+ break;
+ TYPES
+#undef DO_TYPE
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ /* Extract the original value and apply the reloc. */
+ Elf_Data *d = gelf_xlatetom (debugfile, &tmpdata, &rdata,
+ ehdr->e_ident[EI_DATA]);
+ if (d == NULL)
+ return DWFL_E_LIBELF;
+ assert (d == &tmpdata);
+ switch (type)
+ {
+#define DO_TYPE(NAME, Name) \
+ case ELF_T_##NAME: \
+ tmpbuf.Name += (GElf_##Name) value; \
+ break;
+ TYPES
+#undef DO_TYPE
+ default:
+ abort ();
+ }
+ }
+
+ /* Now convert the relocated datum back to the target
+ format. This will write into rdata.d_buf, which
+ points into the raw section data being relocated. */
+ Elf_Data *s = gelf_xlatetof (debugfile, &rdata, &tmpdata,
+ ehdr->e_ident[EI_DATA]);
+ if (s == NULL)
+ return DWFL_E_LIBELF;
+ assert (s == &rdata);
+
+ /* We have applied this relocation! */
+ return DWFL_E_NOERROR;
+ }
+
+ /* Fetch the relocation section and apply each reloc in it. */
+ Elf_Data *reldata = elf_getdata (scn, NULL);
+ if (reldata == NULL)
+ return DWFL_E_LIBELF;
+
+ result = DWFL_E_NOERROR;
+ size_t nrels = shdr->sh_size / shdr->sh_entsize;
+ if (shdr->sh_type == SHT_REL)
+ for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
+ {
+ GElf_Rel rel_mem, *r = gelf_getrel (reldata, relidx, &rel_mem);
+ if (r == NULL)
+ return DWFL_E_LIBELF;
+ result = relocate (r->r_offset, NULL,
+ GELF_R_TYPE (r->r_info),
+ GELF_R_SYM (r->r_info));
+ }
+ else
+ for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
+ {
+ GElf_Rela rela_mem, *r = gelf_getrela (reldata, relidx,
+ &rela_mem);
+ if (r == NULL)
+ return DWFL_E_LIBELF;
+ result = relocate (r->r_offset, &r->r_addend,
+ GELF_R_TYPE (r->r_info),
+ GELF_R_SYM (r->r_info));
+ }
+ if (result != DWFL_E_NOERROR)
+ break;
+ }
+ }
+
+ return result;
+}
diff --git a/elfutils/libebl/ChangeLog b/elfutils/libebl/ChangeLog
index 533a8de0..cb0d0095 100644
--- a/elfutils/libebl/ChangeLog
+++ b/elfutils/libebl/ChangeLog
@@ -1,3 +1,207 @@
+2005-08-13 Roland McGrath <roland@redhat.com>
+
+ * ia64_symbol.c (ia64_machine_flag_check): New function.
+ * libebl_ia64.h: Declare it.
+ * ia64_init.c (ia64_init): Use it.
+
+2005-08-13 Ulrich Drepper <drepper@redhat.com>
+
+ * libebl.h: Add ehdr parameter to ebl_bss_plt_p and
+ ebl_check_special_symbol.
+ * libeblP.h (struct ebl): Adjust callback functions.
+ * eblopenbackend.c: Adjust dummy functions.
+ * ebl_check_special_symbol.c: Add parameter and pass it on.
+ * eblbsspltp.c: Likewise.
+ * ppc_symbol.c (find_dyn_got): With ehdr passed, simplify search for
+ the dynamic section entry.
+ (ppc_check_special_symbol): Add ehdr parameter.
+ (ppc_bss_plt_p): Likewise.
+ * libebl_ppc.h: Adjust prototypes.
+ * ppc64_symbol.c (ppc_check_special_symbol): Add ehdr parameter.
+ (ppc_bss_plt_p): Likewise.
+ * libebl_ppc64.h: Adjust prototypes.
+
+2005-08-12 Roland McGrath <roland@redhat.com>
+
+ * ppc_symbol.c (find_dyn_got): New function, broken out of ...
+ (ppc_bss_plt_p): ... here. Call that.
+ (ppc_check_special_symbol): Use find_dyn_got to fetch value to check
+ against _GLOBAL_OFFSET_TABLE_.
+
+ * libeblP.h (struct ebl): Add bss_plt_p hook.
+ * eblopenbackend.c (default_bss_plt_p): New function.
+ (fill_defaults): Use it.
+ * eblbsspltp.c: New file.
+ * Makefile.am (gen_SOURCES): Add it.
+ * libebl.h: Declare ebl_bss_plt_p.
+ * ppc_symbol.c (ppc_bss_plt_p): New function.
+ * libebl_ppc.h: Declare it.
+ * ppc_init.c (ppc_init): Use it.
+ * ppc64_symbol.c (ppc64_bss_plt_p): New function.
+ * libebl_ppc64.h: Declare it.
+ * ppc64_init.c (ppc64_init): Use it.
+
+ * ebl_check_special_symbol.c: New file.
+ * Makefile.am (gen_SOURCES): Add it.
+ * libebl.h: Declare ebl_check_special_symbol.
+ * libeblP.h (struct ebl): Add check_special_symbol hook.
+ * eblopenbackend.c (default_check_special_symbol): New function.
+ (fill_defaults): Use it.
+ * ppc_symbol.c (ppc_check_special_symbol): New function.
+ * libebl_ppc.h: Add prototype.
+ * ppc_init.c (ppc_init): Use it.
+ * ppc64_symbol.c (ppc64_check_special_symbol): New function.
+ * libebl_ppc64.h: Add prototype.
+ * ppc64_init.c (ppc64_init): Use it.
+
+2005-08-07 Ulrich Drepper <drepper@redhat.com>
+
+ * ppc_init.c: Add support for new DT_PPC_* and R_PPC_* values.
+ * ppc_symbol.c: Likewise.
+ * libebl_ppc.h: Likewise.
+ * ppc64_init.c: There is now also a dynamic_tag_check functions
+ * ppc64_symbol.c: Add dynamic_tag_check.
+ * libebl_ppc64.h: Add prototype.
+ * alpha_init.c: Add support for new DT_ALPHA_* value.
+ * alpha_symbol.c: Likewise.
+ * libebl_alpha.h: Likewise.
+
+2005-08-03 Ulrich Drepper <drepper@redhat.com>
+
+ * libebl_alpha.map: Remove unnecessary exports.
+ * libebl_arm.map: Likewise.
+ * libebl_i386.map: Likewise.
+ * libebl_ia64.map: Likewise.
+ * libebl_ppc.map: Likewise.
+ * libebl_ppc64.map: Likewise.
+ * libebl_sh.map: Likewise.
+ * libebl_sparc.map: Likewise.
+ * libebl_x86_64.map: Likewise.
+
+2005-08-02 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (libebl_a_SOURCES): Add eblelfclass.c, eblelfdata.c,
+ and eblelfmachine.c.
+ * elbopenbackend.c (machines): Add class and data fields. Initialize
+ them.
+ (ebl_openbackend): Initialize machine, class, data fields in result.
+ * libebl.h: Declare Add eblelfclass, eblelfdata, and eblelfmachine.
+ * libeblP.h (Ebl): Add machine, class, data fields.
+
+2005-07-23 Ulrich Drepper <drepper@redhat.com>
+
+ * eblsectionstripp.c: New file.
+ * Makefile.am (gen_SOURCES): Add eblsectionstripp.c.
+ * i386_init.c (i386_init): Install specific debugscn_p callback.
+ * i386_symbol.c (i386_debugscn_p): New function.
+ * libebl.h: Declare ebl_section_strip_p.
+ * libebl_i386.h: Declare i386_debugscn_p.
+
+ * libebl.h: Move Ebl definition to...
+ * libeblP.h: ...here.
+
+2005-07-21 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am (install-ebl-modules): New target, commands from ...
+ (install): ... here. Make this depend on it.
+ (LIBEBL_SUBDIR): New variable, substituted by configure.
+ (install-ebl-modules): Install in $(libdir)/$(LIBEBL_SUBDIR).
+ * eblopenbackend.c (openbackend): Use LIBEBL_SUBDIR in module name.
+
+2005-07-21 Ulrich Drepper <drepper@redhat.com>
+
+ * eblcopyrelocp.c: New file.
+ * Makefile.am (gen_SOURCES): Add eblcopyrelocp.c.
+ * libebl.h: Declare ebl_copy_reloc_p.
+ * eblopenbackend.c (fill_defaults): Fill in copy_reloc_p.
+ (default_copy_reloc_p): New function.
+ * alpha_init.c: Define and use arch-specific copy_reloc_p function.
+ * alpha_symbol.c: Likewise.
+ * arm_init.c: Likewise.
+ * arm_symbol.c: Likewise.
+ * i386_init.c: Likewise.
+ * i386_symbol.c: Likewise.
+ * ia64_init.c: Likewise.
+ * ia64_symbol.c: Likewise.
+ * ppc64_init.c: Likewise.
+ * ppc64_symbol.c: Likewise.
+ * ppc_init.c: Likewise.
+ * ppc_symbol.c: Likewise.
+ * sh_init.c: Likewise.
+ * sh_symbol.c: Likewise.
+ * sparc_init.c: Likewise.
+ * sparc_symbol.c: Likewise.
+ * x86_64_init.c: Likewise.
+ * x86_64_symbol.c: Likewise.
+ * libebl_alpha.h: Declare the copy_reloc_p function.
+ * libebl_arm.h: Likewise.
+ * libebl_i386.h: Likewise.
+ * libebl_ia64.h: Likewise.
+ * libebl_ppc.h: Likewise.
+ * libebl_ppc64.h: Likewise.
+ * libebl_sh.h: Likewise.
+ * libebl_sparc.h: Likewise.
+ * libebl_x86_64.h: Likewise.
+
+2005-05-31 Roland McGrath <roland@redhat.com>
+
+ * Makefile.am (libebl_*_so_SOURCES): Set to $(*_SRCS) so dependency
+ tracking works right.
+
+2005-05-21 Ulrich Drepper <drepper@redhat.com>
+
+ * libebl_x86_64.map: Add x86_64_core_note.
+
+2005-05-19 Roland McGrath <roland@redhat.com>
+
+ * libebl_i386.map: Add i386_reloc_valid_use, i386_reloc_simple_type.
+ * libebl_ppc.map: Add ppc_reloc_simple_type.
+ * libebl_ppc64.map: Add ppc64_reloc_simple_type.
+ * libebl_x86_64.map: Add x86_64_reloc_simple_type.
+
+2005-05-11 Ulrich Drepper <drepper@redhat.com>
+
+ * eblcorenote.c: Handle new AT_* values and files with different
+ endianess.
+ * Makefile.am (x86_64_SRCS): Add x86_64_corenote.c.
+ * x86-64_corenote.c: New file.
+ * x86_64_init.c: Hook in x86_64_corenote.
+ * i386_corenote.c: Make file usable on 64-bit platforms.
+
+ * eblopenbackend.c: If modules version comparison fails, reinitialize
+ hooks.
+
+2005-05-10 Ulrich Drepper <drepper@redhat.com>
+
+ * eblopenbackend.c: Require the init function to return a string.
+ Compare it with MODVERSION from config.h.
+ * alpha_init.c: Change return type. Return MODVERSION or NULL.
+ * arm_init.c: Likewise.
+ * eblopenbackend.c: Likewise.
+ * i386_init.c: Likewise.
+ * ia64_init.c: Likewise.
+ * ppc64_init.c: Likewise.
+ * ppc_init.c: Likewise.
+ * sh_init.c: Likewise.
+ * sparc_init.c: Likewise.
+ * x86_64_init.c: Likewise.
+ * libeblP.h: Adjust ebl_bhinit_t.
+ * libebl_alpha.h: Adjust init function prototype.
+ * libebl_arm.h: Likewise.
+ * libebl_i386.h: Likewise.
+ * libebl_ia64.h: Likewise.
+ * libebl_ppc.h: Likewise.
+ * libebl_ppc64.h: Likewise.
+ * libebl_sh.h: Likewise.
+ * libebl_sparc.h: Likewise.
+ * libebl_x86_64.h: Likewise.
+
+ * mips_destr.c: Removed.
+ * mips_init.c: Removed.
+ * mips_symbol.c: Removed.
+ * libebl_mips.h: Removed.
+ * libebl_mips.map: Removed.
+
2005-05-03 Roland McGrath <roland@redhat.com>
* libebl.h (Ebl): Add `reloc_simple_type' member.
diff --git a/elfutils/libebl/Makefile.am b/elfutils/libebl/Makefile.am
index 3965185a..ead129bd 100644
--- a/elfutils/libebl/Makefile.am
+++ b/elfutils/libebl/Makefile.am
@@ -24,10 +24,11 @@ AM_CFLAGS += -fpic -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 \
INCLUDES = -I$(srcdir) -I$(top_srcdir)/libelf -I$(top_srcdir)/lib -I..
VERSION = 1
PACKAGE_VERSION = @PACKAGE_VERSION@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
lib_LIBRARIES = libebl.a
-modules = i386 sh mips x86_64 ia64 alpha arm sparc ppc ppc64
-noinst_LIBRARIES = libebl_i386_pic.a libebl_sh_pic.a libebl_mips_pic.a \
+modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64
+noinst_LIBRARIES = libebl_i386_pic.a libebl_sh_pic.a \
libebl_x86_64_pic.a libebl_ia64_pic.a libebl_alpha_pic.a \
libebl_arm_pic.a libebl_sparc_pic.a libebl_ppc_pic.a \
libebl_ppc64_pic.a
@@ -46,12 +47,14 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
eblreloctypecheck.c eblrelocvaliduse.c eblrelocsimpletype.c \
ebldynamictagcheck.c eblcorenotetypename.c eblobjnotetypename.c \
eblcorenote.c eblobjnote.c ebldebugscnp.c \
- eblgotpcreloccheck.c
+ eblgotpcreloccheck.c eblcopyrelocp.c eblsectionstripp.c \
+ eblelfclass.c eblelfdata.c eblelfmachine.c \
+ ebl_check_special_symbol.c eblbsspltp.c
libebl_a_SOURCES = $(gen_SOURCES)
i386_SRCS = i386_init.c i386_destr.c i386_symbol.c i386_corenote.c
-libebl_i386_pic_a_SOURCES =
+libebl_i386_pic_a_SOURCES = $(i386_SRCS)
am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
if MUDFLAP
@@ -73,7 +76,7 @@ libebl_i386.so: libebl_i386_pic.a libebl_i386.map
sh_SRCS = sh_init.c sh_destr.c sh_symbol.c
-libebl_sh_pic_a_SOURCES =
+libebl_sh_pic_a_SOURCES = $(sh_SRCS)
am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
libebl_sh_so_SOURCES =
@@ -84,20 +87,8 @@ libebl_sh.so: libebl_sh_pic.a libebl_sh.map
$(textrel_check)
-mips_SRCS = mips_init.c mips_destr.c mips_symbol.c
-libebl_mips_pic_a_SOURCES =
-am_libebl_mips_pic_a_OBJECTS = $(mips_SRCS:.c=.os)
-
-libebl_mips_so_SOURCES =
-libebl_mips.so: libebl_mips_pic.a libebl_mips.map
- $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
- -Wl,--version-script,$(srcdir)/libebl_mips.map \
- -Wl,-z,defs $(libmudflap)
- $(textrel_check)
-
-
-x86_64_SRCS = x86_64_init.c x86_64_destr.c x86_64_symbol.c
-libebl_x86_64_pic_a_SOURCES =
+x86_64_SRCS = x86_64_init.c x86_64_destr.c x86_64_symbol.c x86_64_corenote.c
+libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
libebl_x86_64_so_SOURCES =
@@ -109,7 +100,7 @@ libebl_x86_64.so: libebl_x86_64_pic.a libebl_x86_64.map
ia64_SRCS = ia64_init.c ia64_destr.c ia64_symbol.c
-libebl_ia64_pic_a_SOURCES =
+libebl_ia64_pic_a_SOURCES = $(ia64_SRCS)
am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os)
libebl_ia64_so_SOURCES =
@@ -121,7 +112,7 @@ libebl_ia64.so: libebl_ia64_pic.a libebl_ia64.map
alpha_SRCS = alpha_init.c alpha_destr.c alpha_symbol.c
-libebl_alpha_pic_a_SOURCES =
+libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
libebl_alpha_so_SOURCES =
@@ -133,7 +124,7 @@ libebl_alpha.so: libebl_alpha_pic.a libebl_alpha.map
arm_SRCS = arm_init.c arm_destr.c arm_symbol.c
-libebl_arm_pic_a_SOURCES =
+libebl_arm_pic_a_SOURCES = $(arm_SRCS)
am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
libebl_arm_so_SOURCES =
@@ -145,7 +136,7 @@ libebl_arm.so: libebl_arm_pic.a libebl_arm.map
sparc_SRCS = sparc_init.c sparc_destr.c sparc_symbol.c
-libebl_sparc_pic_a_SOURCES =
+libebl_sparc_pic_a_SOURCES = $(sparc_SRCS)
am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
libebl_sparc_so_SOURCES =
@@ -157,7 +148,7 @@ libebl_sparc.so: libebl_sparc_pic.a libebl_sparc.map
ppc_SRCS = ppc_init.c ppc_destr.c ppc_symbol.c
-libebl_ppc_pic_a_SOURCES =
+libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
libebl_ppc_so_SOURCES =
@@ -169,7 +160,7 @@ libebl_ppc.so: libebl_ppc_pic.a libebl_ppc.map
ppc64_SRCS = ppc64_init.c ppc64_destr.c ppc64_symbol.c
-libebl_ppc64_pic_a_SOURCES =
+libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
libebl_ppc64_so_SOURCES =
@@ -188,19 +179,20 @@ libebl_ppc64.so: libebl_ppc64_pic.a libebl_ppc64.map
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
-install: install-am
- $(mkinstalldirs) $(DESTDIR)$(libdir)/elfutils
+install: install-am install-ebl-modules
+install-ebl-modules:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
for m in $(modules); do \
- $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/elfutils/libebl_$${m}-$(PACKAGE_VERSION).so; \
- ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/elfutils/libebl_$${m}.so; \
+ $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+ ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
done
uninstall: uninstall-am
for m in $(modules); do \
- rm -f $(DESTDIR)$(libdir)/elfutils/libebl_$${m}-$(PACKAGE_VERSION).so; \
- rm -f $(DESTDIR)$(libdir)/elfutils/libebl_$${m}.so; \
+ rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+ rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
done
- rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/elfutils
+ rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
noinst_HEADERS = libeblP.h $(noinst_LIBRARIES:%_pic.a=%.h)
diff --git a/elfutils/libebl/Makefile.in b/elfutils/libebl/Makefile.in
index e43ee333..2c30d604 100644
--- a/elfutils/libebl/Makefile.in
+++ b/elfutils/libebl/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,8 +16,6 @@
-SOURCES = $(libebl_a_SOURCES) $(libebl_alpha_pic_a_SOURCES) $(libebl_arm_pic_a_SOURCES) $(libebl_i386_pic_a_SOURCES) $(libebl_ia64_pic_a_SOURCES) $(libebl_mips_pic_a_SOURCES) $(libebl_ppc64_pic_a_SOURCES) $(libebl_ppc_pic_a_SOURCES) $(libebl_sh_pic_a_SOURCES) $(libebl_sparc_pic_a_SOURCES) $(libebl_x86_64_pic_a_SOURCES) $(libebl_alpha_so_SOURCES) $(libebl_arm_so_SOURCES) $(libebl_i386_so_SOURCES) $(libebl_ia64_so_SOURCES) $(libebl_mips_so_SOURCES) $(libebl_ppc_so_SOURCES) $(libebl_ppc64_so_SOURCES) $(libebl_sh_so_SOURCES) $(libebl_sparc_so_SOURCES) $(libebl_x86_64_so_SOURCES)
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -78,44 +76,63 @@ am__objects_1 = eblopenbackend.$(OBJEXT) eblclosebackend.$(OBJEXT) \
eblrelocsimpletype.$(OBJEXT) ebldynamictagcheck.$(OBJEXT) \
eblcorenotetypename.$(OBJEXT) eblobjnotetypename.$(OBJEXT) \
eblcorenote.$(OBJEXT) eblobjnote.$(OBJEXT) \
- ebldebugscnp.$(OBJEXT) eblgotpcreloccheck.$(OBJEXT)
+ ebldebugscnp.$(OBJEXT) eblgotpcreloccheck.$(OBJEXT) \
+ eblcopyrelocp.$(OBJEXT) eblsectionstripp.$(OBJEXT) \
+ eblelfclass.$(OBJEXT) eblelfdata.$(OBJEXT) \
+ eblelfmachine.$(OBJEXT) ebl_check_special_symbol.$(OBJEXT) \
+ eblbsspltp.$(OBJEXT)
am_libebl_a_OBJECTS = $(am__objects_1)
libebl_a_OBJECTS = $(am_libebl_a_OBJECTS)
libebl_alpha_pic_a_AR = $(AR) $(ARFLAGS)
libebl_alpha_pic_a_LIBADD =
+am__objects_2 = alpha_init.$(OBJEXT) alpha_destr.$(OBJEXT) \
+ alpha_symbol.$(OBJEXT)
libebl_alpha_pic_a_OBJECTS = $(am_libebl_alpha_pic_a_OBJECTS)
libebl_arm_pic_a_AR = $(AR) $(ARFLAGS)
libebl_arm_pic_a_LIBADD =
+am__objects_3 = arm_init.$(OBJEXT) arm_destr.$(OBJEXT) \
+ arm_symbol.$(OBJEXT)
libebl_arm_pic_a_OBJECTS = $(am_libebl_arm_pic_a_OBJECTS)
libebl_i386_pic_a_AR = $(AR) $(ARFLAGS)
libebl_i386_pic_a_LIBADD =
+am__objects_4 = i386_init.$(OBJEXT) i386_destr.$(OBJEXT) \
+ i386_symbol.$(OBJEXT) i386_corenote.$(OBJEXT)
libebl_i386_pic_a_OBJECTS = $(am_libebl_i386_pic_a_OBJECTS)
libebl_ia64_pic_a_AR = $(AR) $(ARFLAGS)
libebl_ia64_pic_a_LIBADD =
+am__objects_5 = ia64_init.$(OBJEXT) ia64_destr.$(OBJEXT) \
+ ia64_symbol.$(OBJEXT)
libebl_ia64_pic_a_OBJECTS = $(am_libebl_ia64_pic_a_OBJECTS)
-libebl_mips_pic_a_AR = $(AR) $(ARFLAGS)
-libebl_mips_pic_a_LIBADD =
-libebl_mips_pic_a_OBJECTS = $(am_libebl_mips_pic_a_OBJECTS)
libebl_ppc64_pic_a_AR = $(AR) $(ARFLAGS)
libebl_ppc64_pic_a_LIBADD =
+am__objects_6 = ppc64_init.$(OBJEXT) ppc64_destr.$(OBJEXT) \
+ ppc64_symbol.$(OBJEXT)
libebl_ppc64_pic_a_OBJECTS = $(am_libebl_ppc64_pic_a_OBJECTS)
libebl_ppc_pic_a_AR = $(AR) $(ARFLAGS)
libebl_ppc_pic_a_LIBADD =
+am__objects_7 = ppc_init.$(OBJEXT) ppc_destr.$(OBJEXT) \
+ ppc_symbol.$(OBJEXT)
libebl_ppc_pic_a_OBJECTS = $(am_libebl_ppc_pic_a_OBJECTS)
libebl_sh_pic_a_AR = $(AR) $(ARFLAGS)
libebl_sh_pic_a_LIBADD =
+am__objects_8 = sh_init.$(OBJEXT) sh_destr.$(OBJEXT) \
+ sh_symbol.$(OBJEXT)
libebl_sh_pic_a_OBJECTS = $(am_libebl_sh_pic_a_OBJECTS)
libebl_sparc_pic_a_AR = $(AR) $(ARFLAGS)
libebl_sparc_pic_a_LIBADD =
+am__objects_9 = sparc_init.$(OBJEXT) sparc_destr.$(OBJEXT) \
+ sparc_symbol.$(OBJEXT)
libebl_sparc_pic_a_OBJECTS = $(am_libebl_sparc_pic_a_OBJECTS)
libebl_x86_64_pic_a_AR = $(AR) $(ARFLAGS)
libebl_x86_64_pic_a_LIBADD =
+am__objects_10 = x86_64_init.$(OBJEXT) x86_64_destr.$(OBJEXT) \
+ x86_64_symbol.$(OBJEXT) x86_64_corenote.$(OBJEXT)
libebl_x86_64_pic_a_OBJECTS = $(am_libebl_x86_64_pic_a_OBJECTS)
am__EXEEXT_1 = libebl_i386.so$(EXEEXT) libebl_sh.so$(EXEEXT) \
- libebl_mips.so$(EXEEXT) libebl_x86_64.so$(EXEEXT) \
- libebl_ia64.so$(EXEEXT) libebl_alpha.so$(EXEEXT) \
- libebl_arm.so$(EXEEXT) libebl_sparc.so$(EXEEXT) \
- libebl_ppc.so$(EXEEXT) libebl_ppc64.so$(EXEEXT)
+ libebl_x86_64.so$(EXEEXT) libebl_ia64.so$(EXEEXT) \
+ libebl_alpha.so$(EXEEXT) libebl_arm.so$(EXEEXT) \
+ libebl_sparc.so$(EXEEXT) libebl_ppc.so$(EXEEXT) \
+ libebl_ppc64.so$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
am_libebl_alpha_so_OBJECTS =
libebl_alpha_so_OBJECTS = $(am_libebl_alpha_so_OBJECTS)
@@ -129,9 +146,6 @@ libebl_i386_so_LDADD = $(LDADD)
am_libebl_ia64_so_OBJECTS =
libebl_ia64_so_OBJECTS = $(am_libebl_ia64_so_OBJECTS)
libebl_ia64_so_LDADD = $(LDADD)
-am_libebl_mips_so_OBJECTS =
-libebl_mips_so_OBJECTS = $(am_libebl_mips_so_OBJECTS)
-libebl_mips_so_LDADD = $(LDADD)
am_libebl_ppc_so_OBJECTS =
libebl_ppc_so_OBJECTS = $(am_libebl_ppc_so_OBJECTS)
libebl_ppc_so_LDADD = $(LDADD)
@@ -156,23 +170,21 @@ CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libebl_a_SOURCES) $(libebl_alpha_pic_a_SOURCES) \
$(libebl_arm_pic_a_SOURCES) $(libebl_i386_pic_a_SOURCES) \
- $(libebl_ia64_pic_a_SOURCES) $(libebl_mips_pic_a_SOURCES) \
- $(libebl_ppc64_pic_a_SOURCES) $(libebl_ppc_pic_a_SOURCES) \
- $(libebl_sh_pic_a_SOURCES) $(libebl_sparc_pic_a_SOURCES) \
- $(libebl_x86_64_pic_a_SOURCES) $(libebl_alpha_so_SOURCES) \
- $(libebl_arm_so_SOURCES) $(libebl_i386_so_SOURCES) \
- $(libebl_ia64_so_SOURCES) $(libebl_mips_so_SOURCES) \
+ $(libebl_ia64_pic_a_SOURCES) $(libebl_ppc64_pic_a_SOURCES) \
+ $(libebl_ppc_pic_a_SOURCES) $(libebl_sh_pic_a_SOURCES) \
+ $(libebl_sparc_pic_a_SOURCES) $(libebl_x86_64_pic_a_SOURCES) \
+ $(libebl_alpha_so_SOURCES) $(libebl_arm_so_SOURCES) \
+ $(libebl_i386_so_SOURCES) $(libebl_ia64_so_SOURCES) \
$(libebl_ppc_so_SOURCES) $(libebl_ppc64_so_SOURCES) \
$(libebl_sh_so_SOURCES) $(libebl_sparc_so_SOURCES) \
$(libebl_x86_64_so_SOURCES)
DIST_SOURCES = $(libebl_a_SOURCES) $(libebl_alpha_pic_a_SOURCES) \
$(libebl_arm_pic_a_SOURCES) $(libebl_i386_pic_a_SOURCES) \
- $(libebl_ia64_pic_a_SOURCES) $(libebl_mips_pic_a_SOURCES) \
- $(libebl_ppc64_pic_a_SOURCES) $(libebl_ppc_pic_a_SOURCES) \
- $(libebl_sh_pic_a_SOURCES) $(libebl_sparc_pic_a_SOURCES) \
- $(libebl_x86_64_pic_a_SOURCES) $(libebl_alpha_so_SOURCES) \
- $(libebl_arm_so_SOURCES) $(libebl_i386_so_SOURCES) \
- $(libebl_ia64_so_SOURCES) $(libebl_mips_so_SOURCES) \
+ $(libebl_ia64_pic_a_SOURCES) $(libebl_ppc64_pic_a_SOURCES) \
+ $(libebl_ppc_pic_a_SOURCES) $(libebl_sh_pic_a_SOURCES) \
+ $(libebl_sparc_pic_a_SOURCES) $(libebl_x86_64_pic_a_SOURCES) \
+ $(libebl_alpha_so_SOURCES) $(libebl_arm_so_SOURCES) \
+ $(libebl_i386_so_SOURCES) $(libebl_ia64_so_SOURCES) \
$(libebl_ppc_so_SOURCES) $(libebl_ppc64_so_SOURCES) \
$(libebl_sh_so_SOURCES) $(libebl_sparc_so_SOURCES) \
$(libebl_x86_64_so_SOURCES)
@@ -189,6 +201,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -202,6 +216,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -210,12 +226,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -283,8 +301,8 @@ target_alias = @target_alias@
@MUDFLAP_TRUE@ -Wunused -Wextra -Wformat=2 -std=gnu99
INCLUDES = -I$(srcdir) -I$(top_srcdir)/libelf -I$(top_srcdir)/lib -I..
lib_LIBRARIES = libebl.a
-modules = i386 sh mips x86_64 ia64 alpha arm sparc ppc ppc64
-noinst_LIBRARIES = libebl_i386_pic.a libebl_sh_pic.a libebl_mips_pic.a \
+modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64
+noinst_LIBRARIES = libebl_i386_pic.a libebl_sh_pic.a \
libebl_x86_64_pic.a libebl_ia64_pic.a libebl_alpha_pic.a \
libebl_arm_pic.a libebl_sparc_pic.a libebl_ppc_pic.a \
libebl_ppc64_pic.a
@@ -301,11 +319,13 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
eblreloctypecheck.c eblrelocvaliduse.c eblrelocsimpletype.c \
ebldynamictagcheck.c eblcorenotetypename.c eblobjnotetypename.c \
eblcorenote.c eblobjnote.c ebldebugscnp.c \
- eblgotpcreloccheck.c
+ eblgotpcreloccheck.c eblcopyrelocp.c eblsectionstripp.c \
+ eblelfclass.c eblelfdata.c eblelfmachine.c \
+ ebl_check_special_symbol.c eblbsspltp.c
libebl_a_SOURCES = $(gen_SOURCES)
i386_SRCS = i386_init.c i386_destr.c i386_symbol.c i386_corenote.c
-libebl_i386_pic_a_SOURCES =
+libebl_i386_pic_a_SOURCES = $(i386_SRCS)
am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
@MUDFLAP_FALSE@libelf = ../libelf/libelf.so
@MUDFLAP_TRUE@libelf = ../libelf/libelf.a
@@ -314,39 +334,35 @@ am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
libebl_i386_so_SOURCES =
sh_SRCS = sh_init.c sh_destr.c sh_symbol.c
-libebl_sh_pic_a_SOURCES =
+libebl_sh_pic_a_SOURCES = $(sh_SRCS)
am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
libebl_sh_so_SOURCES =
-mips_SRCS = mips_init.c mips_destr.c mips_symbol.c
-libebl_mips_pic_a_SOURCES =
-am_libebl_mips_pic_a_OBJECTS = $(mips_SRCS:.c=.os)
-libebl_mips_so_SOURCES =
-x86_64_SRCS = x86_64_init.c x86_64_destr.c x86_64_symbol.c
-libebl_x86_64_pic_a_SOURCES =
+x86_64_SRCS = x86_64_init.c x86_64_destr.c x86_64_symbol.c x86_64_corenote.c
+libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
libebl_x86_64_so_SOURCES =
ia64_SRCS = ia64_init.c ia64_destr.c ia64_symbol.c
-libebl_ia64_pic_a_SOURCES =
+libebl_ia64_pic_a_SOURCES = $(ia64_SRCS)
am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os)
libebl_ia64_so_SOURCES =
alpha_SRCS = alpha_init.c alpha_destr.c alpha_symbol.c
-libebl_alpha_pic_a_SOURCES =
+libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
libebl_alpha_so_SOURCES =
arm_SRCS = arm_init.c arm_destr.c arm_symbol.c
-libebl_arm_pic_a_SOURCES =
+libebl_arm_pic_a_SOURCES = $(arm_SRCS)
am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
libebl_arm_so_SOURCES =
sparc_SRCS = sparc_init.c sparc_destr.c sparc_symbol.c
-libebl_sparc_pic_a_SOURCES =
+libebl_sparc_pic_a_SOURCES = $(sparc_SRCS)
am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
libebl_sparc_so_SOURCES =
ppc_SRCS = ppc_init.c ppc_destr.c ppc_symbol.c
-libebl_ppc_pic_a_SOURCES =
+libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
libebl_ppc_so_SOURCES =
ppc64_SRCS = ppc64_init.c ppc64_destr.c ppc64_symbol.c
-libebl_ppc64_pic_a_SOURCES =
+libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
libebl_ppc64_so_SOURCES =
noinst_HEADERS = libeblP.h $(noinst_LIBRARIES:%_pic.a=%.h)
@@ -441,10 +457,6 @@ libebl_ia64_pic.a: $(libebl_ia64_pic_a_OBJECTS) $(libebl_ia64_pic_a_DEPENDENCIES
-rm -f libebl_ia64_pic.a
$(libebl_ia64_pic_a_AR) libebl_ia64_pic.a $(libebl_ia64_pic_a_OBJECTS) $(libebl_ia64_pic_a_LIBADD)
$(RANLIB) libebl_ia64_pic.a
-libebl_mips_pic.a: $(libebl_mips_pic_a_OBJECTS) $(libebl_mips_pic_a_DEPENDENCIES)
- -rm -f libebl_mips_pic.a
- $(libebl_mips_pic_a_AR) libebl_mips_pic.a $(libebl_mips_pic_a_OBJECTS) $(libebl_mips_pic_a_LIBADD)
- $(RANLIB) libebl_mips_pic.a
libebl_ppc64_pic.a: $(libebl_ppc64_pic_a_OBJECTS) $(libebl_ppc64_pic_a_DEPENDENCIES)
-rm -f libebl_ppc64_pic.a
$(libebl_ppc64_pic_a_AR) libebl_ppc64_pic.a $(libebl_ppc64_pic_a_OBJECTS) $(libebl_ppc64_pic_a_LIBADD)
@@ -475,13 +487,25 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebl_check_special_symbol.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblbackendname.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblbsspltp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblclosebackend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcopyrelocp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcorenote.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcorenotetypename.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebldebugscnp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebldynamictagcheck.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebldynamictagname.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblelfclass.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblelfdata.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblelfmachine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblgotpcreloccheck.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblgstrtab.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblmachineflagcheck.Po@am__quote@
@@ -496,6 +520,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblreloctypename.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblrelocvaliduse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsectionname.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsectionstripp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsectiontypename.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsegmenttypename.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblshflagscombine.Po@am__quote@
@@ -503,6 +528,29 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsymbolbindingname.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsymboltypename.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblwstrtab.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_corenote.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_corenote.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_destr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_symbol.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@@ -715,11 +763,6 @@ libebl_sh.so: libebl_sh_pic.a libebl_sh.map
-Wl,--version-script,$(srcdir)/libebl_sh.map \
-Wl,-z,defs $(libmudflap)
$(textrel_check)
-libebl_mips.so: libebl_mips_pic.a libebl_mips.map
- $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
- -Wl,--version-script,$(srcdir)/libebl_mips.map \
- -Wl,-z,defs $(libmudflap)
- $(textrel_check)
libebl_x86_64.so: libebl_x86_64_pic.a libebl_x86_64.map
$(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-Wl,--version-script,$(srcdir)/libebl_x86_64.map \
@@ -764,19 +807,20 @@ libebl_ppc64.so: libebl_ppc64_pic.a libebl_ppc64.map
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
-install: install-am
- $(mkinstalldirs) $(DESTDIR)$(libdir)/elfutils
+install: install-am install-ebl-modules
+install-ebl-modules:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
for m in $(modules); do \
- $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/elfutils/libebl_$${m}-$(PACKAGE_VERSION).so; \
- ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/elfutils/libebl_$${m}.so; \
+ $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+ ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
done
uninstall: uninstall-am
for m in $(modules); do \
- rm -f $(DESTDIR)$(libdir)/elfutils/libebl_$${m}-$(PACKAGE_VERSION).so; \
- rm -f $(DESTDIR)$(libdir)/elfutils/libebl_$${m}.so; \
+ rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+ rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
done
- rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/elfutils
+ rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/elfutils/libebl/alpha_init.c b/elfutils/libebl/alpha_init.c
index eb80c531..327f3bd0 100644
--- a/elfutils/libebl/alpha_init.c
+++ b/elfutils/libebl/alpha_init.c
@@ -19,7 +19,7 @@
#include <libebl_alpha.h>
-int
+const char *
alpha_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,13 +28,16 @@ alpha_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "Alpha";
eh->reloc_type_name = alpha_reloc_type_name;
eh->reloc_type_check = alpha_reloc_type_check;
+ eh->dynamic_tag_name = alpha_dynamic_tag_name;
+ eh->dynamic_tag_check = alpha_dynamic_tag_check;
+ eh->copy_reloc_p = alpha_copy_reloc_p;
eh->destr = alpha_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/alpha_symbol.c b/elfutils/libebl/alpha_symbol.c
index 4927edce..3fcd1846 100644
--- a/elfutils/libebl/alpha_symbol.c
+++ b/elfutils/libebl/alpha_symbol.c
@@ -92,3 +92,33 @@ alpha_reloc_type_check (int type)
< sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))
&& reloc_map_table[type] != NULL) ? true : false;
}
+
+
+const char *
+alpha_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_ALPHA_PLTRO:
+ return "ALPHA_PLTRO";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+bool
+alpha_dynamic_tag_check (int64_t tag)
+{
+ return tag == DT_ALPHA_PLTRO;
+}
+
+
+/* Check whether given relocation is a copy relocation. */
+bool
+alpha_copy_reloc_p (int reloc)
+{
+ return reloc == R_ALPHA_COPY;
+}
diff --git a/elfutils/libebl/arm_init.c b/elfutils/libebl/arm_init.c
index 3a37f435..a0a65f83 100644
--- a/elfutils/libebl/arm_init.c
+++ b/elfutils/libebl/arm_init.c
@@ -19,7 +19,7 @@
#include <libebl_arm.h>
-int
+const char *
arm_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,13 +28,14 @@ arm_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "Arm";
eh->reloc_type_name = arm_reloc_type_name;
eh->reloc_type_check = arm_reloc_type_check;
+ eh->copy_reloc_p = arm_copy_reloc_p;
eh->destr = arm_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/arm_symbol.c b/elfutils/libebl/arm_symbol.c
index ccd9db29..f4de8be9 100644
--- a/elfutils/libebl/arm_symbol.c
+++ b/elfutils/libebl/arm_symbol.c
@@ -112,3 +112,10 @@ arm_reloc_type_check (int type)
|| (type >= R_ARM_GNU_VTENTRY && type <= R_ARM_THM_PC9)
|| (type >= R_ARM_RXPC25 && type <= R_ARM_RBASE)) ? true : false;
}
+
+/* Check whether given relocation is a copy relocation. */
+bool
+arm_copy_reloc_p (int reloc)
+{
+ return reloc == R_ARM_COPY;
+}
diff --git a/elfutils/libebl/ebl_check_special_symbol.c b/elfutils/libebl/ebl_check_special_symbol.c
new file mode 100644
index 00000000..176e9a6c
--- /dev/null
+++ b/elfutils/libebl/ebl_check_special_symbol.c
@@ -0,0 +1,34 @@
+/* Check special symbol's st_value.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_check_special_symbol (ebl, ehdr, sym, name, destshdr)
+ Ebl *ebl;
+ GElf_Ehdr *ehdr;
+ const GElf_Sym *sym;
+ const char *name;
+ const GElf_Shdr *destshdr;
+{
+ if (ebl == NULL)
+ return false;
+
+ return ebl->check_special_symbol (ebl->elf, ehdr, sym, name, destshdr);
+}
diff --git a/elfutils/libebl/eblbsspltp.c b/elfutils/libebl/eblbsspltp.c
new file mode 100644
index 00000000..62a4bb01
--- /dev/null
+++ b/elfutils/libebl/eblbsspltp.c
@@ -0,0 +1,28 @@
+/* Check if backend uses a bss PLT.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_bss_plt_p (ebl, ehdr)
+ Ebl *ebl;
+ GElf_Ehdr *ehdr;
+{
+ return ebl == NULL ? false : ebl->bss_plt_p (ebl->elf, ehdr);
+}
diff --git a/elfutils/libebl/eblcopyrelocp.c b/elfutils/libebl/eblcopyrelocp.c
new file mode 100644
index 00000000..2d3362a2
--- /dev/null
+++ b/elfutils/libebl/eblcopyrelocp.c
@@ -0,0 +1,28 @@
+/* Check whether given relocation is a copy relocation.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_copy_reloc_p (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl->copy_reloc_p (reloc);
+}
diff --git a/elfutils/libebl/eblcorenote.c b/elfutils/libebl/eblcorenote.c
index 30e46272..725d3a1b 100644
--- a/elfutils/libebl/eblcorenote.c
+++ b/elfutils/libebl/eblcorenote.c
@@ -16,6 +16,9 @@
# include <config.h>
#endif
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
#include <inttypes.h>
#include <stdio.h>
#include <stddef.h>
@@ -30,7 +33,11 @@ ebl_core_note (ebl, name, type, descsz, desc)
uint32_t descsz;
const char *desc;
{
- int class = gelf_getclass (ebl->elf);
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (ebl->elf, &ehdr_mem);
+ assert (ehdr != NULL);
+ int class = ehdr->e_ident[EI_CLASS];
+ int endian = ehdr->e_ident[EI_DATA];
if (! ebl->core_note (name, type, descsz, desc))
/* The machine specific function did not know this type. */
@@ -42,28 +49,45 @@ ebl_core_note (ebl, name, type, descsz, desc)
case NT_AUXV:
;
- size_t cnt;
size_t elsize = (class == ELFCLASS32
? sizeof (Elf32_auxv_t) : sizeof (Elf64_auxv_t));
- for (cnt = 0; (cnt + 1) * elsize <= descsz; ++cnt)
+ for (size_t cnt = 0; (cnt + 1) * elsize <= descsz; ++cnt)
{
- unsigned long int atype;
- unsigned long int val;
+ uintmax_t atype;
+ uintmax_t val;
if (class == ELFCLASS32)
{
Elf32_auxv_t *auxv = &((Elf32_auxv_t *) desc)[cnt];
- atype = auxv->a_type;
- val = auxv->a_un.a_val;
+ if ((endian == ELFDATA2LSB && __BYTE_ORDER == __LITTLE_ENDIAN)
+ || (endian == ELFDATA2MSB && __BYTE_ORDER == __BIG_ENDIAN))
+ {
+ atype = auxv->a_type;
+ val = auxv->a_un.a_val;
+ }
+ else
+ {
+ atype = bswap_32 (auxv->a_type);
+ val = bswap_32 (auxv->a_un.a_val);
+ }
}
else
{
Elf64_auxv_t *auxv = &((Elf64_auxv_t *) desc)[cnt];
- atype = auxv->a_type;
- val = auxv->a_un.a_val;
+ if ((endian == ELFDATA2LSB && __BYTE_ORDER == __LITTLE_ENDIAN)
+ || (endian == ELFDATA2MSB && __BYTE_ORDER == __BIG_ENDIAN))
+ {
+ atype = auxv->a_type;
+ val = auxv->a_un.a_val;
+ }
+ else
+ {
+ atype = bswap_64 (auxv->a_type);
+ val = bswap_64 (auxv->a_un.a_val);
+ }
}
/* XXX Do we need the auxiliary vector info anywhere
@@ -97,9 +121,17 @@ ebl_core_note (ebl, name, type, descsz, desc)
NEW_AT (UCACHEBSIZE);
NEW_AT (IGNOREPPC);
NEW_AT (SECURE);
-
- default:
- at = "???";
+ NEW_AT (SYSINFO);
+ NEW_AT (SYSINFO_EHDR);
+ NEW_AT (L1I_CACHESHAPE);
+ NEW_AT (L1D_CACHESHAPE);
+ NEW_AT (L2_CACHESHAPE);
+ NEW_AT (L3_CACHESHAPE);
+
+ default:;
+ static char buf[30];
+ sprintf (buf, "%ju (AT_?""?""?)", atype);
+ at = buf;
break;
}
@@ -127,7 +159,11 @@ ebl_core_note (ebl, name, type, descsz, desc)
case AT_ICACHEBSIZE:
case AT_UCACHEBSIZE:
case AT_SECURE:
- printf (" %s: %" PRId64 "\n", at, (int64_t) val);
+ case AT_L1I_CACHESHAPE:
+ case AT_L1D_CACHESHAPE:
+ case AT_L2_CACHESHAPE:
+ case AT_L3_CACHESHAPE:
+ printf (" %s: %jd\n", at, val);
break;
case AT_PHDR:
@@ -136,7 +172,9 @@ ebl_core_note (ebl, name, type, descsz, desc)
case AT_ENTRY:
case AT_PLATFORM: /* XXX Get string? */
case AT_HWCAP: /* XXX Print flags? */
- printf (" %s: %#" PRIx64 "\n", at, (uint64_t) val);
+ case AT_SYSINFO:
+ case AT_SYSINFO_EHDR:
+ printf (" %s: %#jx\n", at, val);
break;
}
diff --git a/elfutils/libebl/eblelfclass.c b/elfutils/libebl/eblelfclass.c
new file mode 100644
index 00000000..9108050f
--- /dev/null
+++ b/elfutils/libebl/eblelfclass.c
@@ -0,0 +1,27 @@
+/* Return ELF class.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfclass (ebl)
+ Ebl *ebl;
+{
+ return ebl->class;
+}
diff --git a/elfutils/libebl/eblelfdata.c b/elfutils/libebl/eblelfdata.c
new file mode 100644
index 00000000..a1b84768
--- /dev/null
+++ b/elfutils/libebl/eblelfdata.c
@@ -0,0 +1,27 @@
+/* Return ELF data encoding.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfdata (ebl)
+ Ebl *ebl;
+{
+ return ebl->data;
+}
diff --git a/elfutils/libebl/eblelfmachine.c b/elfutils/libebl/eblelfmachine.c
new file mode 100644
index 00000000..74847b1e
--- /dev/null
+++ b/elfutils/libebl/eblelfmachine.c
@@ -0,0 +1,27 @@
+/* Return ELF machine.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfmachine (ebl)
+ Ebl *ebl;
+{
+ return ebl->machine;
+}
diff --git a/elfutils/libebl/eblopenbackend.c b/elfutils/libebl/eblopenbackend.c
index cc03fe70..aef289ca 100644
--- a/elfutils/libebl/eblopenbackend.c
+++ b/elfutils/libebl/eblopenbackend.c
@@ -36,83 +36,83 @@ static const struct
const char *prefix;
int prefix_len;
int em;
+ int class;
+ int data;
} machines[] =
{
- { "i386", "elf_i386", "i386", 4, EM_386 },
- { "ia64", "elf_ia64", "ia64", 4, EM_IA_64 },
- { "alpha", "elf_alpha", "alpha", 5, EM_ALPHA },
- { "x86_64", "elf_x86_64", "x86_64", 6, EM_X86_64 },
- { "sh", "elf_sh", "sh", 2, EM_SH },
- { "arm", "ebl_arm", "arm", 3, EM_ARM },
- { "sparc", "elf_sparcv9", "sparc", 5, EM_SPARCV9 },
- { "sparc", "elf_sparc", "sparc", 5, EM_SPARC },
- { "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS },
-
- { "m32", "elf_m32", "m32", 3, EM_M32 },
- { "m68k", "elf_m68k", "m68k", 4, EM_68K },
- { "m88k", "elf_m88k", "m88k", 4, EM_88K },
- { "i860", "elf_i860", "i860", 4, EM_860 },
- { "mips", "elf_mips", "mips", 4, EM_MIPS },
- { "s370", "ebl_s370", "s370", 4, EM_S370 },
- { "mips", "elf_mipsel", "mips", 4, EM_MIPS_RS3_LE },
- { "parisc", "elf_parisc", "parisc", 6, EM_PARISC },
- { "vpp500", "elf_vpp500", "vpp500", 5, EM_VPP500 },
- { "sparc", "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS },
- { "i960", "elf_i960", "i960", 4, EM_960 },
- { "ppc", "elf_ppc", "ppc", 3, EM_PPC },
- { "ppc64", "elf_ppc64", "ppc64", 5, EM_PPC64 },
- { "s390", "ebl_s390", "s390", 4, EM_S390 },
- { "v800", "ebl_v800", "v800", 4, EM_V800 },
- { "fr20", "ebl_fr20", "fr20", 4, EM_FR20 },
- { "rh32", "ebl_rh32", "rh32", 4, EM_RH32 },
- { "rce", "ebl_rce", "rce", 3, EM_RCE },
- { "tricore", "elf_tricore", "tricore", 7, EM_TRICORE },
- { "arc", "elf_arc", "arc", 3, EM_ARC },
- { "h8", "elf_h8_300", "h8_300", 6, EM_H8_300 },
- { "h8", "elf_h8_300h", "h8_300h", 6, EM_H8_300H },
- { "h8", "elf_h8s", "h8s", 6, EM_H8S },
- { "h8", "elf_h8_500", "h8_500", 6, EM_H8_500 },
- { "mips_x", "elf_mips_x", "mips_x", 6, EM_MIPS_X },
- { "coldfire", "elf_coldfire", "coldfire", 8, EM_COLDFIRE },
- { "m68k", "elf_68hc12", "68hc12", 6, EM_68HC12 },
- { "mma", "elf_mma", "mma", 3, EM_MMA },
- { "pcp", "elf_pcp", "pcp", 3, EM_PCP },
- { "ncpu", "elf_ncpu", "ncpu", 4, EM_NCPU },
- { "ndr1", "elf_ndr1", "ndr1", 4, EM_NDR1 },
- { "starcore", "elf_starcore", "starcore", 8, EM_STARCORE },
- { "me16", "elf_me16", "em16", 4, EM_ME16 },
- { "st100", "elf_st100", "st100", 5, EM_ST100 },
- { "tinyj", "elf_tinyj", "tinyj", 5, EM_TINYJ },
- { "pdsp", "elf_pdsp", "pdsp", 4, EM_PDSP },
- { "fx66", "elf_fx66", "fx66", 4, EM_FX66 },
- { "st9plus", "elf_st9plus", "st9plus", 7, EM_ST9PLUS },
- { "st7", "elf_st7", "st7", 3, EM_ST7 },
- { "m68k", "elf_68hc16", "68hc16", 6, EM_68HC16 },
- { "m68k", "elf_68hc11", "68hc11", 6, EM_68HC11 },
- { "m68k", "elf_68hc08", "68hc08", 6, EM_68HC08 },
- { "m68k", "elf_68hc05", "68hc05", 6, EM_68HC05 },
- { "svx", "elf_svx", "svx", 3, EM_SVX },
- { "st19", "elf_st19", "st19", 4, EM_ST19 },
- { "vax", "elf_vax", "vax", 3, EM_VAX },
- { "cris", "elf_cris", "cris", 4, EM_CRIS },
- { "javelin", "elf_javelin", "javelin", 7, EM_JAVELIN },
- { "firepath", "elf_firepath", "firepath", 8, EM_FIREPATH },
- { "zsp", "elf_zsp", "zsp", 3, EM_ZSP},
- { "mmix", "elf_mmix", "mmix", 4, EM_MMIX },
- { "hunay", "elf_huany", "huany", 5, EM_HUANY },
- { "prism", "elf_prism", "prism", 5, EM_PRISM },
- { "avr", "elf_avr", "avr", 3, EM_AVR },
- { "fr30", "elf_fr30", "fr30", 4, EM_FR30 },
- { "dv10", "elf_dv10", "dv10", 4, EM_D10V },
- { "dv30", "elf_dv30", "dv30", 4, EM_D30V },
- { "v850", "elf_v850", "v850", 4, EM_V850 },
- { "m32r", "elf_m32r", "m32r", 4, EM_M32R },
- { "mn10300", "elf_mn10300", "mn10300", 7, EM_MN10300 },
- { "mn10200", "elf_mn10200", "mn10200", 7, EM_MN10200 },
- { "pj", "elf_pj", "pj", 2, EM_PJ },
- { "openrisc", "elf_openrisc", "openrisc", 8, EM_OPENRISC },
- { "arc", "elf_arc_a5", "arc_a5", 6, EM_ARC_A5 },
- { "xtensa", "elf_xtensa", "xtensa", 6, EM_XTENSA },
+ { "i386", "elf_i386", "i386", 4, EM_386, ELFCLASS32, ELFDATA2LSB },
+ { "ia64", "elf_ia64", "ia64", 4, EM_IA_64, ELFCLASS64, ELFDATA2LSB },
+ { "alpha", "elf_alpha", "alpha", 5, EM_ALPHA, ELFCLASS64, ELFDATA2LSB },
+ { "x86_64", "elf_x86_64", "x86_64", 6, EM_X86_64, ELFCLASS64, ELFDATA2LSB },
+ { "ppc", "elf_ppc", "ppc", 3, EM_PPC, ELFCLASS32, ELFDATA2MSB },
+ { "ppc64", "elf_ppc64", "ppc64", 5, EM_PPC64, ELFCLASS64, ELFDATA2MSB },
+ // XXX class and machine fields need to be filled in for all archs.
+ { "sh", "elf_sh", "sh", 2, EM_SH, 0, 0 },
+ { "arm", "ebl_arm", "arm", 3, EM_ARM, 0, 0 },
+ { "sparc", "elf_sparcv9", "sparc", 5, EM_SPARCV9, 0, 0 },
+ { "sparc", "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 },
+ { "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 },
+
+ { "m32", "elf_m32", "m32", 3, EM_M32, 0, 0 },
+ { "m68k", "elf_m68k", "m68k", 4, EM_68K, 0, 0 },
+ { "m88k", "elf_m88k", "m88k", 4, EM_88K, 0, 0 },
+ { "i860", "elf_i860", "i860", 4, EM_860, 0, 0 },
+ { "s370", "ebl_s370", "s370", 4, EM_S370, 0, 0 },
+ { "parisc", "elf_parisc", "parisc", 6, EM_PARISC, 0, 0 },
+ { "vpp500", "elf_vpp500", "vpp500", 5, EM_VPP500, 0, 0 },
+ { "sparc", "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS, 0, 0 },
+ { "i960", "elf_i960", "i960", 4, EM_960, 0, 0 },
+ { "s390", "ebl_s390", "s390", 4, EM_S390, 0, 0 },
+ { "v800", "ebl_v800", "v800", 4, EM_V800, 0, 0 },
+ { "fr20", "ebl_fr20", "fr20", 4, EM_FR20, 0, 0 },
+ { "rh32", "ebl_rh32", "rh32", 4, EM_RH32, 0, 0 },
+ { "rce", "ebl_rce", "rce", 3, EM_RCE, 0, 0 },
+ { "tricore", "elf_tricore", "tricore", 7, EM_TRICORE, 0, 0 },
+ { "arc", "elf_arc", "arc", 3, EM_ARC, 0, 0 },
+ { "h8", "elf_h8_300", "h8_300", 6, EM_H8_300, 0, 0 },
+ { "h8", "elf_h8_300h", "h8_300h", 6, EM_H8_300H, 0, 0 },
+ { "h8", "elf_h8s", "h8s", 6, EM_H8S, 0, 0 },
+ { "h8", "elf_h8_500", "h8_500", 6, EM_H8_500, 0, 0 },
+ { "coldfire", "elf_coldfire", "coldfire", 8, EM_COLDFIRE, 0, 0 },
+ { "m68k", "elf_68hc12", "68hc12", 6, EM_68HC12, 0, 0 },
+ { "mma", "elf_mma", "mma", 3, EM_MMA, 0, 0 },
+ { "pcp", "elf_pcp", "pcp", 3, EM_PCP, 0, 0 },
+ { "ncpu", "elf_ncpu", "ncpu", 4, EM_NCPU, 0, 0 },
+ { "ndr1", "elf_ndr1", "ndr1", 4, EM_NDR1, 0, 0 },
+ { "starcore", "elf_starcore", "starcore", 8, EM_STARCORE, 0, 0 },
+ { "me16", "elf_me16", "em16", 4, EM_ME16, 0, 0 },
+ { "st100", "elf_st100", "st100", 5, EM_ST100, 0, 0 },
+ { "tinyj", "elf_tinyj", "tinyj", 5, EM_TINYJ, 0, 0 },
+ { "pdsp", "elf_pdsp", "pdsp", 4, EM_PDSP, 0, 0 },
+ { "fx66", "elf_fx66", "fx66", 4, EM_FX66, 0, 0 },
+ { "st9plus", "elf_st9plus", "st9plus", 7, EM_ST9PLUS, 0, 0 },
+ { "st7", "elf_st7", "st7", 3, EM_ST7, 0, 0 },
+ { "m68k", "elf_68hc16", "68hc16", 6, EM_68HC16, 0, 0 },
+ { "m68k", "elf_68hc11", "68hc11", 6, EM_68HC11, 0, 0 },
+ { "m68k", "elf_68hc08", "68hc08", 6, EM_68HC08, 0, 0 },
+ { "m68k", "elf_68hc05", "68hc05", 6, EM_68HC05, 0, 0 },
+ { "svx", "elf_svx", "svx", 3, EM_SVX, 0, 0 },
+ { "st19", "elf_st19", "st19", 4, EM_ST19, 0, 0 },
+ { "vax", "elf_vax", "vax", 3, EM_VAX, 0, 0 },
+ { "cris", "elf_cris", "cris", 4, EM_CRIS, 0, 0 },
+ { "javelin", "elf_javelin", "javelin", 7, EM_JAVELIN, 0, 0 },
+ { "firepath", "elf_firepath", "firepath", 8, EM_FIREPATH, 0, 0 },
+ { "zsp", "elf_zsp", "zsp", 3, EM_ZSP, 0, 0 },
+ { "mmix", "elf_mmix", "mmix", 4, EM_MMIX, 0, 0 },
+ { "hunay", "elf_huany", "huany", 5, EM_HUANY, 0, 0 },
+ { "prism", "elf_prism", "prism", 5, EM_PRISM, 0, 0 },
+ { "avr", "elf_avr", "avr", 3, EM_AVR, 0, 0 },
+ { "fr30", "elf_fr30", "fr30", 4, EM_FR30, 0, 0 },
+ { "dv10", "elf_dv10", "dv10", 4, EM_D10V, 0, 0 },
+ { "dv30", "elf_dv30", "dv30", 4, EM_D30V, 0, 0 },
+ { "v850", "elf_v850", "v850", 4, EM_V850, 0, 0 },
+ { "m32r", "elf_m32r", "m32r", 4, EM_M32R, 0, 0 },
+ { "mn10300", "elf_mn10300", "mn10300", 7, EM_MN10300, 0, 0 },
+ { "mn10200", "elf_mn10200", "mn10200", 7, EM_MN10200, 0, 0 },
+ { "pj", "elf_pj", "pj", 2, EM_PJ, 0, 0 },
+ { "openrisc", "elf_openrisc", "openrisc", 8, EM_OPENRISC, 0, 0 },
+ { "arc", "elf_arc_a5", "arc_a5", 6, EM_ARC_A5, 0, 0 },
+ { "xtensa", "elf_xtensa", "xtensa", 6, EM_XTENSA, 0, 0 },
};
#define nmachines (sizeof (machines) / sizeof (machines[0]))
@@ -152,31 +152,17 @@ static bool default_core_note (const char *name, uint32_t type,
static bool default_object_note (const char *name, uint32_t type,
uint32_t descsz, const char *desc);
static bool default_debugscn_p (const char *name);
+static bool default_copy_reloc_p (int reloc);
+static bool default_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym,
+ const char *name,
+ const GElf_Shdr *destshdr);
+static bool default_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr);
-/* Find an appropriate backend for the file associated with ELF. */
-static Ebl *
-openbackend (elf, emulation, machine)
- Elf *elf;
- const char *emulation;
- GElf_Half machine;
+static void
+fill_defaults (Ebl *result)
{
- Ebl *result;
- size_t cnt;
-
- /* First allocate the data structure for the result. We do this
- here since this assures that the structure is always large
- enough. */
- result = (Ebl *) calloc (1, sizeof (Ebl));
- if (result == NULL)
- {
- // XXX uncomment
- // __libebl_seterror (ELF_E_NOMEM);
- return NULL;
- }
-
- /* Fill in the default callbacks. The initializer for the machine
- specific module can overwrite the values. */
result->object_type_name = default_object_type_name;
result->reloc_type_name = default_reloc_type_name;
result->reloc_type_check = default_reloc_type_check;
@@ -199,7 +185,37 @@ openbackend (elf, emulation, machine)
result->core_note = default_core_note;
result->object_note = default_object_note;
result->debugscn_p = default_debugscn_p;
+ result->copy_reloc_p = default_copy_reloc_p;
+ result->check_special_symbol = default_check_special_symbol;
+ result->bss_plt_p = default_bss_plt_p;
result->destr = default_destr;
+}
+
+
+/* Find an appropriate backend for the file associated with ELF. */
+static Ebl *
+openbackend (elf, emulation, machine)
+ Elf *elf;
+ const char *emulation;
+ GElf_Half machine;
+{
+ Ebl *result;
+ size_t cnt;
+
+ /* First allocate the data structure for the result. We do this
+ here since this assures that the structure is always large
+ enough. */
+ result = (Ebl *) calloc (1, sizeof (Ebl));
+ if (result == NULL)
+ {
+ // XXX uncomment
+ // __libebl_seterror (ELF_E_NOMEM);
+ return NULL;
+ }
+
+ /* Fill in the default callbacks. The initializer for the machine
+ specific module can overwrite the values. */
+ fill_defaults (result);
/* XXX Currently all we do is to look at 'e_machine' value in the
ELF header. With an internal mapping table from EM_* value to
@@ -217,11 +233,19 @@ openbackend (elf, emulation, machine)
/* Well, we know the emulation name now. */
result->emulation = machines[cnt].emulation;
+ result->machine = machines[cnt].em;
+ result->class = machines[cnt].class;
+ result->data = machines[cnt].data;
+
+#ifndef LIBEBL_SUBDIR
+# define LIBEBL_SUBDIR PACKAGE
+#endif
+#define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/"
+
/* Give it a try. At least the machine type matches. First
try to load the module. */
char dsoname[100];
- strcpy (stpcpy (stpcpy (dsoname,
- "$ORIGIN/../$LIB/elfutils/libebl_"),
+ strcpy (stpcpy (stpcpy (dsoname, ORIGINDIR "libebl_"),
machines[cnt].dsoname),
".so");
@@ -239,6 +263,8 @@ openbackend (elf, emulation, machine)
{
/* We managed to load the object. Now see whether the
initialization function likes our file. */
+ static const char version[] = MODVERSION;
+ const char *modversion;
ebl_bhinit_t initp;
char symname[machines[cnt].prefix_len + sizeof "_init"];
@@ -247,7 +273,8 @@ openbackend (elf, emulation, machine)
initp = (ebl_bhinit_t) dlsym (h, symname);
if (initp != NULL
- && initp (elf, machine, result, sizeof (Ebl)) == 0)
+ && (modversion = initp (elf, machine, result, sizeof (Ebl)))
+ && strcmp (version, modversion) == 0)
{
/* We found a module to handle our file. */
result->dlhandle = h;
@@ -269,6 +296,7 @@ openbackend (elf, emulation, machine)
result->dlhandle = NULL;
result->elf = elf;
result->name = machines[cnt].prefix;
+ fill_defaults (result);
return result;
}
@@ -278,6 +306,7 @@ openbackend (elf, emulation, machine)
result->elf = elf;
result->emulation = "<unknown>";
result->name = "<unknown>";
+ fill_defaults (result);
return result;
}
@@ -525,3 +554,26 @@ default_debugscn_p (const char *name)
return false;
}
+
+static bool
+default_copy_reloc_p (int reloc __attribute__ ((unused)))
+{
+ return false;
+}
+
+static bool
+default_check_special_symbol (Elf *elf __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ const GElf_Sym *sym __attribute__ ((unused)),
+ const char *name __attribute__ ((unused)),
+ const GElf_Shdr *destshdr __attribute__ ((unused)))
+{
+ return false;
+}
+
+static bool
+default_bss_plt_p (Elf *elf __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)))
+{
+ return false;
+}
diff --git a/elfutils/libebl/eblsectionstripp.c b/elfutils/libebl/eblsectionstripp.c
new file mode 100644
index 00000000..77a22cac
--- /dev/null
+++ b/elfutils/libebl/eblsectionstripp.c
@@ -0,0 +1,52 @@
+/* Check whether section can be stripped.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libeblP.h"
+
+
+bool
+ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
+ const char *name, bool remove_comment,
+ bool only_remove_debug)
+{
+ /* If only debug information should be removed check the name. There
+ is unfortunately no other way. */
+ if (unlikely (only_remove_debug))
+ {
+ if (ebl_debugscn_p (ebl, name))
+ return true;
+
+ if (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL)
+ {
+ Elf_Scn *scn_l = elf_getscn (ebl->elf, (shdr)->sh_info);
+ GElf_Shdr shdr_mem_l;
+ GElf_Shdr *shdr_l = gelf_getshdr (scn_l, &shdr_mem_l);
+ if (shdr_l == NULL)
+ {
+ const char *s_l = elf_strptr (ebl->elf, ehdr->e_shstrndx,
+ shdr_l->sh_name);
+ if (s_l != NULL && ebl_debugscn_p (ebl, s_l))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return SECTION_STRIP_P (shdr, name, remove_comment);
+}
diff --git a/elfutils/libebl/i386_corenote.c b/elfutils/libebl/i386_corenote.c
index c0f2bcce..3a123e92 100644
--- a/elfutils/libebl/i386_corenote.c
+++ b/elfutils/libebl/i386_corenote.c
@@ -17,6 +17,7 @@
#endif
#include <elf.h>
+#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/time.h>
@@ -24,29 +25,33 @@
#include <libebl_i386.h>
-/* We cannot include <sys/procfs.h> since it is available only on x86
- systems. */
+/* We cannot include <sys/procfs.h> since the definition would be for
+ the host platform and not always x86 as required here. */
struct elf_prstatus
{
struct
{
- int si_signo; /* Signal number. */
- int si_code; /* Extra code. */
- int si_errno; /* Errno. */
+ int32_t si_signo; /* Signal number. */
+ int32_t si_code; /* Extra code. */
+ int32_t si_errno; /* Errno. */
} pr_info; /* Info associated with signal. */
- short int pr_cursig; /* Current signal. */
- unsigned long int pr_sigpend; /* Set of pending signals. */
- unsigned long int pr_sighold; /* Set of held signals. */
- __pid_t pr_pid;
- __pid_t pr_ppid;
- __pid_t pr_pgrp;
- __pid_t pr_sid;
- struct timeval pr_utime; /* User time. */
- struct timeval pr_stime; /* System time. */
- struct timeval pr_cutime; /* Cumulative user time. */
- struct timeval pr_cstime; /* Cumulative system time. */
- unsigned long int pr_reg[17]; /* GP registers. */
- int pr_fpvalid; /* True if math copro being used. */
+ int16_t pr_cursig; /* Current signal. */
+ uint32_t pr_sigpend; /* Set of pending signals. */
+ uint32_t pr_sighold; /* Set of held signals. */
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ struct i386_timeval
+ {
+ int32_t tv_sec;
+ int32_t tv_usec;
+ } pr_utime; /* User time. */
+ struct i386_timeval pr_stime; /* System time. */
+ struct i386_timeval pr_cutime; /* Cumulative user time. */
+ struct i386_timeval pr_cstime; /* Cumulative system time. */
+ uint32_t pr_reg[17]; /* GP registers. */
+ int32_t pr_fpvalid; /* True if math copro being used. */
};
@@ -56,13 +61,13 @@ struct elf_prpsinfo
char pr_sname; /* Char for pr_state. */
char pr_zomb; /* Zombie. */
char pr_nice; /* Nice val. */
- unsigned long int pr_flag; /* Flags. */
- unsigned short int pr_uid;
- unsigned short int pr_gid;
- int pr_pid;
- int pr_ppid;
- int pr_pgrp;
- int pr_sid;
+ uint32_t pr_flag; /* Flags. */
+ uint16_t pr_uid;
+ uint16_t pr_gid;
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
/* Lots missing */
char pr_fname[16]; /* Filename of executable. */
char pr_psargs[80]; /* Initial part of arg list. */
@@ -87,27 +92,34 @@ i386_core_note (name, type, descsz, desc)
struct elf_prstatus *stat = (struct elf_prstatus *) desc;
- printf (" SIGINFO: signo: %d, code = %d, errno = %d\n"
- " signal: %hd, pending: %#08lx, holding: %#08lx\n"
- " pid: %d, ppid = %d, pgrp = %d, sid = %d\n"
- " utime: %6ld.%06lds, stime: %6ld.%06lds\n"
- " cutime: %6ld.%06lds, cstime: %6ld.%06lds\n"
- " eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n"
- " esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n"
- " eip: %08lx eflags: %08lx, original eax: %08lx\n"
- " cs: %04lx ds: %04lx es: %04lx fs: %04lx gs: %04lx"
- " ss: %04lx\n\n"
-,
- stat->pr_info. si_signo,
- stat->pr_info. si_code,
- stat->pr_info. si_errno,
+ printf (" SIGINFO: signo: %" PRId32 ", code = %" PRId32
+ ", errno = %" PRId32 "\n"
+ " signal: %" PRId16 ", pending: %08" PRIx32
+ ", holding: %8" PRIx32 "\n"
+ " pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
+ ", sid = %" PRId32 "\n"
+ " utime: %6" PRId32 ".%06" PRId32
+ "s, stime: %6" PRId32 ".%06" PRId32 "s\n"
+ " cutime: %6" PRId32 ".%06" PRId32
+ "s, cstime: %6" PRId32 ".%06" PRId32 "s\n"
+ " eax: %08" PRIx32 " ebx: %08" PRIx32 " ecx: %08" PRIx32
+ " edx: %08" PRIx32 "\n"
+ " esi: %08" PRIx32 " edi: %08" PRIx32 " ebp: %08" PRIx32
+ " esp: %08" PRIx32 "\n"
+ " eip: %08" PRIx32 " eflags: %08" PRIx32
+ " original eax: %08" PRIx32 "\n"
+ " cs: %04" PRIx32 " ds: %04" PRIx32 " es: %04" PRIx32
+ " fs: %04" PRIx32 " gs: %04" PRIx32 " ss: %04" PRIx32 "\n\n",
+ stat->pr_info.si_signo,
+ stat->pr_info.si_code,
+ stat->pr_info.si_errno,
stat->pr_cursig,
stat->pr_sigpend, stat->pr_sighold,
stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
- stat->pr_utime.tv_sec, (long int) stat->pr_utime.tv_usec,
- stat->pr_stime.tv_sec, (long int) stat->pr_stime.tv_usec,
- stat->pr_cutime.tv_sec, (long int) stat->pr_cutime.tv_usec,
- stat->pr_cstime.tv_sec, (long int) stat->pr_cstime.tv_usec,
+ stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
+ stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
+ stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
+ stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
stat->pr_reg[6], stat->pr_reg[0], stat->pr_reg[1],
stat->pr_reg[2], stat->pr_reg[3], stat->pr_reg[4],
stat->pr_reg[5], stat->pr_reg[15], stat->pr_reg[12],
@@ -128,8 +140,9 @@ i386_core_note (name, type, descsz, desc)
struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
printf (" state: %c (%hhd), zombie: %hhd, nice: %hhd\n"
- " flags: %08lx, uid: %hd, gid: %hd\n"
- " pid: %d, ppid: %d, pgrp: %d, sid: %d\n"
+ " flags: %08" PRIx32 ", uid: %" PRId16 ", gid: %" PRId16"\n"
+ " pid: %" PRId32 ", ppid: %" PRId32 ", pgrp: %" PRId32
+ ", sid: %" PRId32 "\n"
" fname: %.16s\n"
" args: %.80s\n\n",
info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
diff --git a/elfutils/libebl/i386_init.c b/elfutils/libebl/i386_init.c
index 007d0281..264f3ef7 100644
--- a/elfutils/libebl/i386_init.c
+++ b/elfutils/libebl/i386_init.c
@@ -19,7 +19,7 @@
#include <libebl_i386.h>
-int
+const char *
i386_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,7 +28,7 @@ i386_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "Intel 80386";
@@ -38,7 +38,10 @@ i386_init (elf, machine, eh, ehlen)
eh->reloc_simple_type = i386_reloc_simple_type;
eh->gotpc_reloc_check = i386_gotpc_reloc_check;
eh->core_note = i386_core_note;
+ generic_debugscn_p = eh->debugscn_p;
+ eh->debugscn_p = i386_debugscn_p;
+ eh->copy_reloc_p = i386_copy_reloc_p;
eh->destr = i386_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/i386_symbol.c b/elfutils/libebl/i386_symbol.c
index 8f32eb86..e9eded23 100644
--- a/elfutils/libebl/i386_symbol.c
+++ b/elfutils/libebl/i386_symbol.c
@@ -19,6 +19,7 @@
#include <assert.h>
#include <elf.h>
#include <stddef.h>
+#include <string.h>
#include <libebl_i386.h>
@@ -143,3 +144,20 @@ i386_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
return ELF_T_NUM;
}
}
+
+/* Check section name for being that of a debug informatino section. */
+bool (*generic_debugscn_p) (const char *);
+bool
+i386_debugscn_p (const char *name)
+{
+ return (generic_debugscn_p (name)
+ || strcmp (name, ".stab") == 0
+ || strcmp (name, ".stabstr") == 0);
+}
+
+/* Check whether given relocation is a copy relocation. */
+bool
+i386_copy_reloc_p (int reloc)
+{
+ return reloc == R_386_COPY;
+}
diff --git a/elfutils/libebl/ia64_init.c b/elfutils/libebl/ia64_init.c
index 6a6f129d..f5c3f364 100644
--- a/elfutils/libebl/ia64_init.c
+++ b/elfutils/libebl/ia64_init.c
@@ -19,7 +19,7 @@
#include <libebl_ia64.h>
-int
+const char *
ia64_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,7 +28,7 @@ ia64_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "Intel IA-64";
@@ -36,7 +36,9 @@ ia64_init (elf, machine, eh, ehlen)
eh->reloc_type_check = ia64_reloc_type_check;
eh->segment_type_name = ia64_segment_type_name;
eh->dynamic_tag_name = ia64_dynamic_tag_name;
+ eh->copy_reloc_p = ia64_copy_reloc_p;
+ eh->machine_flag_check = ia64_machine_flag_check;
eh->destr = ia64_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/ia64_symbol.c b/elfutils/libebl/ia64_symbol.c
index 55f89baf..2975285b 100644
--- a/elfutils/libebl/ia64_symbol.c
+++ b/elfutils/libebl/ia64_symbol.c
@@ -178,3 +178,17 @@ ia64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
}
return NULL;
}
+
+/* Check whether given relocation is a copy relocation. */
+bool
+ia64_copy_reloc_p (int reloc)
+{
+ return reloc == R_IA64_COPY;
+}
+
+/* Check whether machine flags are valid. */
+bool
+ia64_machine_flag_check (GElf_Word flags)
+{
+ return ((flags &~ EF_IA_64_ABI64) == 0);
+}
diff --git a/elfutils/libebl/libebl.h b/elfutils/libebl/libebl.h
index 3c18d716..8b51aef7 100644
--- a/elfutils/libebl/libebl.h
+++ b/elfutils/libebl/libebl.h
@@ -22,90 +22,8 @@
#include <elf-knowledge.h>
-/* Backend handle. */
-typedef struct ebl
-{
- /* Machine name. */
- const char *name;
-
- /* Emulation name. */
- const char *emulation;
-
- /* The libelf handle (if known). */
- Elf *elf;
-
- /* Return symbol representaton of object file type. */
- const char *(*object_type_name) (int, char *, size_t);
-
- /* Return symbolic representation of relocation type. */
- const char *(*reloc_type_name) (int, char *, size_t);
-
- /* Check relocation type. */
- bool (*reloc_type_check) (int);
-
- /* Check if relocation type is for simple absolute relocations. */
- Elf_Type (*reloc_simple_type) (Elf *, int);
-
- /* Check relocation type use. */
- bool (*reloc_valid_use) (Elf *, int);
-
- /* Return true if the symbol type is that referencing the GOT. */
- bool (*gotpc_reloc_check) (Elf *, int);
-
- /* Return symbolic representation of segment type. */
- const char *(*segment_type_name) (int, char *, size_t);
-
- /* Return symbolic representation of section type. */
- const char *(*section_type_name) (int, char *, size_t);
-
- /* Return section name. */
- const char *(*section_name) (int, int, char *, size_t);
-
- /* Return next machine flag name. */
- const char *(*machine_flag_name) (GElf_Word *);
-
- /* Check whether machine flags are valid. */
- bool (*machine_flag_check) (GElf_Word);
-
- /* Return symbolic representation of symbol type. */
- const char *(*symbol_type_name) (int, char *, size_t);
-
- /* Return symbolic representation of symbol binding. */
- const char *(*symbol_binding_name) (int, char *, size_t);
-
- /* Return symbolic representation of dynamic tag. */
- const char *(*dynamic_tag_name) (int64_t, char *, size_t);
-
- /* Check dynamic tag. */
- bool (*dynamic_tag_check) (int64_t);
-
- /* Combine section header flags values. */
- GElf_Word (*sh_flags_combine) (GElf_Word, GElf_Word);
-
- /* Return symbolic representation of OS ABI. */
- const char *(*osabi_name) (int, char *, size_t);
-
- /* Name of a note entry type for core files. */
- const char *(*core_note_type_name) (uint32_t, char *, size_t);
-
- /* Name of a note entry type for object files. */
- const char *(*object_note_type_name) (uint32_t, char *, size_t);
-
- /* Handle core note. */
- bool (*core_note) (const char *, uint32_t, uint32_t, const char *);
-
- /* Handle object file note. */
- bool (*object_note) (const char *, uint32_t, uint32_t, const char *);
-
- /* Check section name for being that of a debug informatino section. */
- bool (*debugscn_p) (const char *);
-
- /* Destructor for ELF backend handle. */
- void (*destr) (struct ebl *);
-
- /* Internal data. */
- void *dlhandle;
-} Ebl;
+/* Opaque type for the handle. */
+typedef struct ebl Ebl;
/* Get backend handle for object associated with ELF handle. */
@@ -119,6 +37,18 @@ extern Ebl *ebl_openbackend_emulation (const char *emulation);
extern void ebl_closebackend (Ebl *bh);
+/* Information about the descriptor. */
+
+/* Get ELF machine. */
+extern int ebl_get_elfmachine (Ebl *ebl) __attribute__ ((__pure__));
+
+/* Get ELF class. */
+extern int ebl_get_elfclass (Ebl *ebl) __attribute__ ((__pure__));
+
+/* Get ELF data encoding. */
+extern int ebl_get_elfdata (Ebl *ebl) __attribute__ ((__pure__));
+
+
/* Function to call the callback functions including default ELF
handling. */
@@ -182,6 +112,12 @@ extern const char *ebl_dynamic_tag_name (Ebl *ebl, int64_t tag,
/* Check dynamic tag. */
extern bool ebl_dynamic_tag_check (Ebl *ebl, int64_t tag);
+/* Check whether given symbol's st_value and st_size are OK despite failing
+ normal checks. */
+extern bool ebl_check_special_symbol (Ebl *ebl, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym, const char *name,
+ const GElf_Shdr *destshdr);
+
/* Return combined section header flags value. */
extern GElf_Word ebl_sh_flags_combine (Ebl *ebl, GElf_Word flags1,
GElf_Word flags2);
@@ -209,6 +145,17 @@ extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
/* Check section name for being that of a debug informatino section. */
extern bool ebl_debugscn_p (Ebl *ebl, const char *name);
+/* Check whether given relocation is a copy relocation. */
+extern bool ebl_copy_reloc_p (Ebl *ebl, int reloc);
+
+/* Check whether section should be stripped. */
+extern bool ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr,
+ const GElf_Shdr *shdr, const char *name,
+ bool remove_comment, bool only_remove_debug);
+
+/* Check if backend uses a bss PLT in this file. */
+extern bool ebl_bss_plt_p (Ebl *ebl, GElf_Ehdr *ehdr);
+
/* ELF string table handling. */
struct Ebl_Strtab;
diff --git a/elfutils/libebl/libeblP.h b/elfutils/libebl/libeblP.h
index cf53212c..e3696f96 100644
--- a/elfutils/libebl/libeblP.h
+++ b/elfutils/libebl/libeblP.h
@@ -1,5 +1,5 @@
/* Internal definitions for interface for libebl.
- Copyright (C) 2000, 2001, 2002, 2004 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -19,8 +19,109 @@
#include <libintl.h>
+/* Backend handle. */
+struct ebl
+{
+ /* Machine name. */
+ const char *name;
+
+ /* Emulation name. */
+ const char *emulation;
+
+ /* ELF machine, class, and data encoding. */
+ int machine;
+ int class;
+ int data;
+
+ /* The libelf handle (if known). */
+ Elf *elf;
+
+ /* Return symbol representaton of object file type. */
+ const char *(*object_type_name) (int, char *, size_t);
+
+ /* Return symbolic representation of relocation type. */
+ const char *(*reloc_type_name) (int, char *, size_t);
+
+ /* Check relocation type. */
+ bool (*reloc_type_check) (int);
+
+ /* Check if relocation type is for simple absolute relocations. */
+ Elf_Type (*reloc_simple_type) (Elf *, int);
+
+ /* Check relocation type use. */
+ bool (*reloc_valid_use) (Elf *, int);
+
+ /* Return true if the symbol type is that referencing the GOT. */
+ bool (*gotpc_reloc_check) (Elf *, int);
+
+ /* Return symbolic representation of segment type. */
+ const char *(*segment_type_name) (int, char *, size_t);
+
+ /* Return symbolic representation of section type. */
+ const char *(*section_type_name) (int, char *, size_t);
+
+ /* Return section name. */
+ const char *(*section_name) (int, int, char *, size_t);
+
+ /* Return next machine flag name. */
+ const char *(*machine_flag_name) (GElf_Word *);
+
+ /* Check whether machine flags are valid. */
+ bool (*machine_flag_check) (GElf_Word);
+
+ /* Return symbolic representation of symbol type. */
+ const char *(*symbol_type_name) (int, char *, size_t);
+
+ /* Return symbolic representation of symbol binding. */
+ const char *(*symbol_binding_name) (int, char *, size_t);
+
+ /* Return symbolic representation of dynamic tag. */
+ const char *(*dynamic_tag_name) (int64_t, char *, size_t);
+
+ /* Check dynamic tag. */
+ bool (*dynamic_tag_check) (int64_t);
+
+ /* Combine section header flags values. */
+ GElf_Word (*sh_flags_combine) (GElf_Word, GElf_Word);
+
+ /* Return symbolic representation of OS ABI. */
+ const char *(*osabi_name) (int, char *, size_t);
+
+ /* Name of a note entry type for core files. */
+ const char *(*core_note_type_name) (uint32_t, char *, size_t);
+
+ /* Name of a note entry type for object files. */
+ const char *(*object_note_type_name) (uint32_t, char *, size_t);
+
+ /* Handle core note. */
+ bool (*core_note) (const char *, uint32_t, uint32_t, const char *);
+
+ /* Handle object file note. */
+ bool (*object_note) (const char *, uint32_t, uint32_t, const char *);
+
+ /* Check section name for being that of a debug informatino section. */
+ bool (*debugscn_p) (const char *);
+
+ /* Check whether given relocation is a copy relocation. */
+ bool (*copy_reloc_p) (int);
+
+ /* Check whether given symbol's value is ok despite normal checks. */
+ bool (*check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *,
+ const char *, const GElf_Shdr *);
+
+ /* Check if backend uses a bss PLT in this file. */
+ bool (*bss_plt_p) (Elf *, GElf_Ehdr *);
+
+ /* Destructor for ELF backend handle. */
+ void (*destr) (struct ebl *);
+
+ /* Internal data. */
+ void *dlhandle;
+};
+
+
/* Type of the initialization functions in the backend modules. */
-typedef int (*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *, size_t);
+typedef const char *(*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *, size_t);
/* gettext helper macros. */
diff --git a/elfutils/libebl/libebl_alpha.h b/elfutils/libebl/libebl_alpha.h
index 36d7dadc..24a3500e 100644
--- a/elfutils/libebl/libebl_alpha.h
+++ b/elfutils/libebl/libebl_alpha.h
@@ -1,5 +1,5 @@
/* Interface for libebl_alpha module.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int alpha_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *alpha_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void alpha_destr (Ebl *bh);
@@ -30,4 +31,13 @@ extern const char *alpha_reloc_type_name (int type, char *buf, size_t len);
/* Check relocation type. */
extern bool alpha_reloc_type_check (int type);
+/* Name of dynamic tag. */
+extern const char *alpha_dynamic_tag_name (int64_t tag, char *buf, size_t len);
+
+/* Check dynamic tag. */
+extern bool alpha_dynamic_tag_check (int64_t tag);
+
+/* Check whether given relocation is a copy relocation. */
+extern bool alpha_copy_reloc_p (int reloc);
+
#endif /* libebl_alpha.h */
diff --git a/elfutils/libebl/libebl_alpha.map b/elfutils/libebl/libebl_alpha.map
index aa66ad75..fa092c61 100644
--- a/elfutils/libebl/libebl_alpha.map
+++ b/elfutils/libebl/libebl_alpha.map
@@ -1,10 +1,6 @@
ELFUTILS_1.0 {
global:
- alpha_backend_name;
- alpha_destr;
alpha_init;
- alpha_reloc_type_check;
- alpha_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_arm.h b/elfutils/libebl/libebl_arm.h
index 8aade439..18bb99c4 100644
--- a/elfutils/libebl/libebl_arm.h
+++ b/elfutils/libebl/libebl_arm.h
@@ -1,5 +1,5 @@
/* Interface for libebl_arm module.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int arm_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *arm_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void arm_destr (Ebl *bh);
@@ -30,4 +31,7 @@ extern const char *arm_reloc_type_name (int type, char *buf, size_t len);
/* Check relocation type. */
extern bool arm_reloc_type_check (int type);
+/* Check whether given relocation is a copy relocation. */
+extern bool arm_copy_reloc_p (int reloc);
+
#endif /* libebl_arm.h */
diff --git a/elfutils/libebl/libebl_arm.map b/elfutils/libebl/libebl_arm.map
index d389526c..51c7726d 100644
--- a/elfutils/libebl/libebl_arm.map
+++ b/elfutils/libebl/libebl_arm.map
@@ -1,10 +1,6 @@
ELFUTILS_1.0 {
global:
- arm_backend_name;
- arm_destr;
arm_init;
- arm_reloc_type_check;
- arm_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_i386.h b/elfutils/libebl/libebl_i386.h
index 166a6072..ef2b3199 100644
--- a/elfutils/libebl/libebl_i386.h
+++ b/elfutils/libebl/libebl_i386.h
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int i386_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *i386_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void i386_destr (Ebl *bh);
@@ -43,4 +44,11 @@ extern bool i386_gotpc_reloc_check (Elf *elf, int type);
extern bool i386_core_note (const char *name, uint32_t type, uint32_t descsz,
const char *desc);
+/* Check section name for being that of a debug informatino section. */
+extern bool i386_debugscn_p (const char *name);
+extern bool (*generic_debugscn_p) (const char *);
+
+/* Check whether given relocation is a copy relocation. */
+extern bool i386_copy_reloc_p (int reloc);
+
#endif /* libebl_i386.h */
diff --git a/elfutils/libebl/libebl_i386.map b/elfutils/libebl/libebl_i386.map
index 38513247..48b4b047 100644
--- a/elfutils/libebl/libebl_i386.map
+++ b/elfutils/libebl/libebl_i386.map
@@ -1,11 +1,6 @@
ELFUTILS_1.0 {
global:
- i386_backend_name;
- i386_core_note;
- i386_destr;
i386_init;
- i386_reloc_type_check;
- i386_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_ia64.h b/elfutils/libebl/libebl_ia64.h
index 19e73fe8..e5cf49de 100644
--- a/elfutils/libebl/libebl_ia64.h
+++ b/elfutils/libebl/libebl_ia64.h
@@ -1,5 +1,5 @@
/* Interface for libebl_ia64 module.
- Copyright (C) 2002, 2003 Red Hat, Inc.
+ Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int ia64_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *ia64_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void ia64_destr (Ebl *bh);
@@ -36,4 +37,11 @@ extern const char *ia64_segment_type_name (int segment, char *buf, size_t len);
/* Name of dynamic tag. */
extern const char *ia64_dynamic_tag_name (int64_t tag, char *buf, size_t len);
+/* Check whether given relocation is a copy relocation. */
+extern bool ia64_copy_reloc_p (int reloc);
+
+/* Check whether machine flags are valid. */
+extern bool ia64_machine_flag_check (GElf_Word flags);
+
+
#endif /* libebl_ia64.h */
diff --git a/elfutils/libebl/libebl_ia64.map b/elfutils/libebl/libebl_ia64.map
index f67042c6..82d65e2c 100644
--- a/elfutils/libebl/libebl_ia64.map
+++ b/elfutils/libebl/libebl_ia64.map
@@ -1,10 +1,6 @@
ELFUTILS_1.0 {
global:
- ia64_backend_name;
- ia64_destr;
ia64_init;
- ia64_reloc_type_check;
- ia64_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_mips.h b/elfutils/libebl/libebl_mips.h
deleted file mode 100644
index 167eab30..00000000
--- a/elfutils/libebl/libebl_mips.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Interface for libebl_mips module.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
-
- This program is Open Source software; you can redistribute it and/or
- modify it under the terms of the Open Software License version 1.0 as
- published by the Open Source Initiative.
-
- You should have received a copy of the Open Software License along
- with this program; if not, you may obtain a copy of the Open Software
- License version 1.0 from http://www.opensource.org/licenses/osl.php or
- by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
- 3001 King Ranch Road, Ukiah, CA 95482. */
-
-#ifndef _LIBEBL_MIPS_H
-#define _LIBEBL_MIPS_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor. */
-extern int mips_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
-
-/* Destructor. */
-extern void mips_destr (Ebl *bh);
-
-
-/* Function to get relocation type name. */
-extern const char *mips_reloc_type_name (int type, char *buf, size_t len);
-
-/* Function to get segment type name. */
-extern const char *mips_segment_type_name (int type, char *buf, size_t len);
-
-/* Function to get setion type name. */
-extern const char *mips_section_type_name (int type, char *buf, size_t len);
-
-/* Function to get machine flag name. */
-extern const char *mips_machine_flag_name (Elf64_Word *flags);
-
-/* Function to get dynamic tag name. */
-extern const char *mips_dynamic_tag_name (int64_t tag, char *buf, size_t len);
-
-#endif /* libebl_mips.h */
diff --git a/elfutils/libebl/libebl_mips.map b/elfutils/libebl/libebl_mips.map
deleted file mode 100644
index 9ddd366b..00000000
--- a/elfutils/libebl/libebl_mips.map
+++ /dev/null
@@ -1,14 +0,0 @@
-ELFUTILS_1.0 {
- global:
- mips_backend_name;
- mips_destr;
- mips_dynamic_tag_name;
- mips_init;
- mips_machine_flag_name;
- mips_reloc_type_name;
- mips_section_type_name;
- mips_segment_type_name;
-
- local:
- *;
-};
diff --git a/elfutils/libebl/libebl_ppc.h b/elfutils/libebl/libebl_ppc.h
index 5370ed0f..67e64afc 100644
--- a/elfutils/libebl/libebl_ppc.h
+++ b/elfutils/libebl/libebl_ppc.h
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int ppc_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *ppc_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void ppc_destr (Ebl *bh);
@@ -40,4 +41,23 @@ extern Elf_Type ppc_reloc_simple_type (Elf *elf, int type);
extern bool ppc_core_note (const char *name, uint32_t type, uint32_t descsz,
const char *desc);
+/* Name of dynamic tag. */
+extern const char *ppc_dynamic_tag_name (int64_t tag, char *buf, size_t len);
+
+/* Check dynamic tag. */
+extern bool ppc_dynamic_tag_check (int64_t tag);
+
+/* Check whether given relocation is a copy relocation. */
+extern bool ppc_copy_reloc_p (int reloc);
+
+/* Check whether given symbol's st_value and st_size are OK despite normal
+ checks. */
+extern bool ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym, const char *name,
+ const GElf_Shdr *destshdr);
+
+/* Check if backend uses a bss PLT in this file. */
+extern bool ppc_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr);
+
+
#endif /* libebl_ppc.h */
diff --git a/elfutils/libebl/libebl_ppc.map b/elfutils/libebl/libebl_ppc.map
index 03bbfcc4..de0c432a 100644
--- a/elfutils/libebl/libebl_ppc.map
+++ b/elfutils/libebl/libebl_ppc.map
@@ -1,10 +1,6 @@
ELFUTILS_1.0 {
global:
- ppc_backend_name;
- ppc_destr;
ppc_init;
- ppc_reloc_type_check;
- ppc_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_ppc64.h b/elfutils/libebl/libebl_ppc64.h
index 41ca0229..e03a1a7c 100644
--- a/elfutils/libebl/libebl_ppc64.h
+++ b/elfutils/libebl/libebl_ppc64.h
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int ppc64_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *ppc64_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void ppc64_destr (Ebl *bh);
@@ -43,4 +44,20 @@ extern bool ppc64_core_note (const char *name, uint32_t type, uint32_t descsz,
/* Name of dynamic tag. */
extern const char *ppc64_dynamic_tag_name (int64_t tag, char *buf, size_t len);
+/* Check dynamic tag. */
+extern bool ppc64_dynamic_tag_check (int64_t tag);
+
+/* Check whether given relocation is a copy relocation. */
+extern bool ppc64_copy_reloc_p (int reloc);
+
+/* Check whether given symbol's st_value and st_size are OK despite normal
+ checks. */
+extern bool ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym, const char *name,
+ const GElf_Shdr *destshdr);
+
+/* Check if backend uses a bss PLT in this file. */
+extern bool ppc64_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr);
+
+
#endif /* libebl_ppc.h */
diff --git a/elfutils/libebl/libebl_ppc64.map b/elfutils/libebl/libebl_ppc64.map
index 2d0d556a..0c3842c7 100644
--- a/elfutils/libebl/libebl_ppc64.map
+++ b/elfutils/libebl/libebl_ppc64.map
@@ -1,10 +1,6 @@
ELFUTILS_1.0 {
global:
- ppc64_backend_name;
- ppc64_destr;
ppc64_init;
- ppc64_reloc_type_check;
- ppc64_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_sh.h b/elfutils/libebl/libebl_sh.h
index 40e2a8c2..32b029a7 100644
--- a/elfutils/libebl/libebl_sh.h
+++ b/elfutils/libebl/libebl_sh.h
@@ -1,5 +1,5 @@
/* Interface for libebl_sh module.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int sh_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *sh_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void sh_destr (Ebl *bh);
@@ -27,4 +28,7 @@ extern void sh_destr (Ebl *bh);
/* Function to get relocation type name. */
extern const char *sh_reloc_type_name (int type, char *buf, size_t len);
+/* Check whether given relocation is a copy relocation. */
+extern bool sh_copy_reloc_p (int reloc);
+
#endif /* libebl_sh.h */
diff --git a/elfutils/libebl/libebl_sh.map b/elfutils/libebl/libebl_sh.map
index 252720a9..a5130c18 100644
--- a/elfutils/libebl/libebl_sh.map
+++ b/elfutils/libebl/libebl_sh.map
@@ -1,9 +1,6 @@
ELFUTILS_1.0 {
global:
- sh_backend_name;
- sh_destr;
sh_init;
- sh_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_sparc.h b/elfutils/libebl/libebl_sparc.h
index c06228ed..077db170 100644
--- a/elfutils/libebl/libebl_sparc.h
+++ b/elfutils/libebl/libebl_sparc.h
@@ -1,5 +1,5 @@
/* Interface for libebl_sparc module.
- Copyright (C) 2002 Red Hat, Inc.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int sparc_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *sparc_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void sparc_destr (Ebl *bh);
@@ -34,4 +35,7 @@ extern bool sparc_reloc_type_check (int type);
extern bool sparc_core_note (const char *name, uint32_t type, uint32_t descsz,
const char *desc);
+/* Check whether given relocation is a copy relocation. */
+extern bool sparc_copy_reloc_p (int reloc);
+
#endif /* libebl_sparc.h */
diff --git a/elfutils/libebl/libebl_sparc.map b/elfutils/libebl/libebl_sparc.map
index 7ca60383..c7c9f1b9 100644
--- a/elfutils/libebl/libebl_sparc.map
+++ b/elfutils/libebl/libebl_sparc.map
@@ -1,10 +1,6 @@
ELFUTILS_1.0 {
global:
- sparc_backend_name;
- sparc_destr;
sparc_init;
- sparc_reloc_type_check;
- sparc_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/libebl_x86_64.h b/elfutils/libebl/libebl_x86_64.h
index a520c9cc..025edb63 100644
--- a/elfutils/libebl/libebl_x86_64.h
+++ b/elfutils/libebl/libebl_x86_64.h
@@ -18,7 +18,8 @@
/* Constructor. */
-extern int x86_64_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen);
+extern const char *x86_64_init (Elf *elf, GElf_Half machine, Ebl *eh,
+ size_t ehlen);
/* Destructor. */
extern void x86_64_destr (Ebl *bh);
@@ -40,4 +41,7 @@ extern Elf_Type x86_64_reloc_simple_type (Elf *elf, int type);
extern bool x86_64_core_note (const char *name, uint32_t type, uint32_t descsz,
const char *desc);
+/* Check whether given relocation is a copy relocation. */
+extern bool x86_64_copy_reloc_p (int reloc);
+
#endif /* libebl_x86_64.h */
diff --git a/elfutils/libebl/libebl_x86_64.map b/elfutils/libebl/libebl_x86_64.map
index bf07cb9c..528a7908 100644
--- a/elfutils/libebl/libebl_x86_64.map
+++ b/elfutils/libebl/libebl_x86_64.map
@@ -1,10 +1,6 @@
ELFUTILS_1.0 {
global:
- x86_64_backend_name;
- x86_64_destr;
x86_64_init;
- x86_64_reloc_type_check;
- x86_64_reloc_type_name;
local:
*;
diff --git a/elfutils/libebl/mips_init.c b/elfutils/libebl/mips_init.c
deleted file mode 100644
index 1c107375..00000000
--- a/elfutils/libebl/mips_init.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Initialization of MIPS specific backend library.
- Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2000.
-
- This program is Open Source software; you can redistribute it and/or
- modify it under the terms of the Open Software License version 1.0 as
- published by the Open Source Initiative.
-
- You should have received a copy of the Open Software License along
- with this program; if not, you may obtain a copy of the Open Software
- License version 1.0 from http://www.opensource.org/licenses/osl.php or
- by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
- 3001 King Ranch Road, Ukiah, CA 95482. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <libebl_mips.h>
-
-
-int
-mips_init (elf, machine, eh, ehlen)
- Elf *elf __attribute__ ((unused));
- GElf_Half machine __attribute__ ((unused));
- Ebl *eh;
- size_t ehlen;
-{
- /* Check whether the Elf_BH object has a sufficent size. */
- if (ehlen < sizeof (Ebl))
- return 1;
-
- /* We handle it. */
- if (machine != EM_MIPS)
- eh->name = "MIPS R3000 big-endian";
- else
- eh->name = "MIPS R3000 little-endian";
-
- eh->reloc_type_name = mips_reloc_type_name;
- eh->segment_type_name = mips_segment_type_name;
- eh->section_type_name = mips_section_type_name;
- eh->machine_flag_name = mips_machine_flag_name;
- eh->dynamic_tag_name = mips_dynamic_tag_name;
- eh->destr = mips_destr;
-
- return 0;
-}
diff --git a/elfutils/libebl/mips_symbol.c b/elfutils/libebl/mips_symbol.c
deleted file mode 100644
index 71ad927a..00000000
--- a/elfutils/libebl/mips_symbol.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* MIPS specific symbolic name handling.
- Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
- Written by Ulrich Drepper <drepper@redhat.com>, 2000.
-
- This program is Open Source software; you can redistribute it and/or
- modify it under the terms of the Open Software License version 1.0 as
- published by the Open Source Initiative.
-
- You should have received a copy of the Open Software License along
- with this program; if not, you may obtain a copy of the Open Software
- License version 1.0 from http://www.opensource.org/licenses/osl.php or
- by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
- 3001 King Ranch Road, Ukiah, CA 95482. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <elf.h>
-#include <stddef.h>
-
-#include <libebl_mips.h>
-
-
-/* Return of the backend. */
-const char *
-mips_backend_name (void)
-{
- return "mips";
-}
-
-
-/* Determine relocation type string for MIPS. */
-const char *
-mips_reloc_type_name (int type, char *buf __attribute__ ((unused)),
- size_t len __attribute__ ((unused)))
-{
- static const char *map_table[] =
- {
- [R_MIPS_NONE] = "MIPS_NONE",
- [R_MIPS_16] = "MIPS_16",
- [R_MIPS_32] = "MIPS_32",
- [R_MIPS_REL32] = "MIPS_REL32",
- [R_MIPS_26] = "MIPS_26",
- [R_MIPS_HI16] = "MIPS_HI16",
- [R_MIPS_LO16] = "MIPS_LO16",
- [R_MIPS_GPREL16] = "MIPS_GPREL16",
- [R_MIPS_LITERAL] = "MIPS_LITERAL",
- [R_MIPS_GOT16] = "MIPS_GOT16",
- [R_MIPS_PC16] = "MIPS_PC16",
- [R_MIPS_CALL16] = "MIPS_CALL16",
- [R_MIPS_GPREL32] = "MIPS_GPREL32",
- [R_MIPS_SHIFT5] = "MIPS_SHIFT5",
- [R_MIPS_SHIFT6] = "MIPS_SHIFT6",
- [R_MIPS_64] = "MIPS_64",
- [R_MIPS_GOT_DISP] = "MIPS_GOT_DISP",
- [R_MIPS_GOT_PAGE] = "MIPS_GOT_PAGE",
- [R_MIPS_GOT_OFST] = "MIPS_GOT_OFST",
- [R_MIPS_GOT_HI16] = "MIPS_GOT_HI16",
- [R_MIPS_GOT_LO16] = "MIPS_GOT_LO16",
- [R_MIPS_SUB] = "MIPS_SUB",
- [R_MIPS_INSERT_A] = "MIPS_INSERT_A",
- [R_MIPS_INSERT_B] = "MIPS_INSERT_B",
- [R_MIPS_DELETE] = "MIPS_DELETE",
- [R_MIPS_HIGHER] = "MIPS_HIGHER",
- [R_MIPS_HIGHEST] = "MIPS_HIGHEST",
- [R_MIPS_CALL_HI16] = "MIPS_CALL_HI16",
- [R_MIPS_CALL_LO16] = "MIPS_CALL_LO16",
- [R_MIPS_SCN_DISP] = "MIPS_SCN_DISP",
- [R_MIPS_REL16] = "MIPS_REL16",
- [R_MIPS_ADD_IMMEDIATE] = "MIPS_ADD_IMMEDIATE",
- [R_MIPS_PJUMP] = "MIPS_PJUMP",
- [R_MIPS_RELGOT] = "MIPS_RELGOT",
- [R_MIPS_JALR] = "MIPS_JALR"
- };
-
- if (type < 0 || type >= R_MIPS_NUM)
- return NULL;
-
- return map_table[type];
-}
-
-
-const char *
-mips_segment_type_name (int type, char *buf __attribute__ ((unused)),
- size_t len __attribute__ ((unused)))
-{
- static const struct
- {
- int type;
- const char *str;
- } mips_segments[] =
- {
- { PT_MIPS_REGINFO, "MIPS_REGINFO" },
- { PT_MIPS_RTPROC, "MIPS_RTPROC" },
- { PT_MIPS_OPTIONS, "MIPS_OPTIONS" }
- };
-#define nsegments (sizeof (mips_segments) / sizeof (mips_segments[0]))
- size_t cnt;
-
- for (cnt = 0; cnt < nsegments; ++cnt)
- if (type == mips_segments[cnt].type)
- return mips_segments[cnt].str;
-
- /* We don't know the segment type. */
- return NULL;
-}
-
-
-const char *
-mips_section_type_name (int type, char *buf __attribute__ ((unused)),
- size_t len __attribute__ ((unused)))
-{
- static const struct
- {
- int type;
- const char *str;
- } mips_sections[] =
- {
- { SHT_MIPS_LIBLIST, "MIPS_LIBLIST" },
- { SHT_MIPS_MSYM, "MIPS_MSYM" },
- { SHT_MIPS_CONFLICT, "MIPS_CONFLICT" },
- { SHT_MIPS_GPTAB, "MIPS_GPTAB" },
- { SHT_MIPS_UCODE, "MIPS_UCODE" },
- { SHT_MIPS_DEBUG, "MIPS_DEBUG" },
- { SHT_MIPS_REGINFO, "MIPS_REGINFO" },
- { SHT_MIPS_PACKAGE, "MIPS_PACKAGE" },
- { SHT_MIPS_PACKSYM, "MIPS_PACKSYM" },
- { SHT_MIPS_RELD, "MIPS_RELD" },
- { SHT_MIPS_IFACE, "MIPS_IFACE" },
- { SHT_MIPS_CONTENT, "MIPS_CONTENT" },
- { SHT_MIPS_OPTIONS, "MIPS_OPTIONS" },
- { SHT_MIPS_SHDR, "MIPS_SHDR" },
- { SHT_MIPS_FDESC, "MIPS_FDESC" },
- { SHT_MIPS_EXTSYM, "MIPS_EXTSYM" },
- { SHT_MIPS_DENSE, "MIPS_DENSE" },
- { SHT_MIPS_PDESC, "MIPS_PDESC" },
- { SHT_MIPS_LOCSYM, "MIPS_LOCSYM" },
- { SHT_MIPS_AUXSYM, "MIPS_AUXSYM" },
- { SHT_MIPS_OPTSYM, "MIPS_OPTSYM" },
- { SHT_MIPS_LOCSTR, "MIPS_LOCSTR" },
- { SHT_MIPS_LINE, "MIPS_LINE" },
- { SHT_MIPS_RFDESC, "MIPS_RFDESC" },
- { SHT_MIPS_DELTASYM, "MIPS_DELTASYM" },
- { SHT_MIPS_DELTAINST, "MIPS_DELTAINST" },
- { SHT_MIPS_DELTACLASS, "MIPS_DELTACLASS" },
- { SHT_MIPS_DWARF, "MIPS_DWARF" },
- { SHT_MIPS_DELTADECL, "MIPS_DELTADECL" },
- { SHT_MIPS_SYMBOL_LIB, "MIPS_SYMBOL_LIB" },
- { SHT_MIPS_EVENTS, "MIPS_EVENTS" },
- { SHT_MIPS_TRANSLATE, "MIPS_TRANSLATE" },
- { SHT_MIPS_PIXIE, "MIPS_PIXIE" },
- { SHT_MIPS_XLATE, "MIPS_XLATE" },
- { SHT_MIPS_XLATE_DEBUG, "MIPS_XLATE_DEBUG" },
- { SHT_MIPS_WHIRL, "MIPS_WHIRL" },
- { SHT_MIPS_EH_REGION, "MIPS_EH_REGION" },
- { SHT_MIPS_XLATE_OLD, "MIPS_XLATE_OLD" },
- { SHT_MIPS_PDR_EXCEPTION, "MIPS_PDR_EXCEPTION" }
- };
-#define nsections (sizeof (mips_sections) / sizeof (mips_sections[0]))
- size_t cnt;
-
- for (cnt = 0; cnt < nsections; ++cnt)
- if (type == mips_sections[cnt].type)
- return mips_sections[cnt].str;
-
- /* We don't know the section type. */
- return NULL;
-}
-
-
-const char *
-mips_machine_flag_name (Elf64_Word *flags)
-{
- static const struct
- {
- unsigned int mask;
- unsigned int flag;
- const char *str;
- } mips_flags[] =
- {
- { EF_MIPS_NOREORDER, EF_MIPS_NOREORDER, "noreorder" },
- { EF_MIPS_PIC, EF_MIPS_PIC, "pic" },
- { EF_MIPS_CPIC, EF_MIPS_CPIC, "cpic" },
- { EF_MIPS_ABI2, EF_MIPS_ABI2, "abi2" },
- { EF_MIPS_ARCH, E_MIPS_ARCH_1, "mips1" },
- { EF_MIPS_ARCH, E_MIPS_ARCH_2, "mips2" },
- { EF_MIPS_ARCH, E_MIPS_ARCH_3, "mips3" },
- { EF_MIPS_ARCH, E_MIPS_ARCH_4, "mips4" },
- { EF_MIPS_ARCH, E_MIPS_ARCH_5, "mips5" }
- };
-#define nflags (sizeof (mips_flags) / sizeof (mips_flags[0]))
- size_t cnt;
-
- for (cnt = 0; cnt < nflags; ++cnt)
- if ((*flags & mips_flags[cnt].mask) == mips_flags[cnt].flag)
- {
- *flags &= ~mips_flags[cnt].mask;
- return mips_flags[cnt].str;
- }
-
- /* We don't know the flag. */
- return NULL;
-}
-
-
-const char *
-mips_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
- size_t len __attribute__ ((unused)))
-{
- static const struct
- {
- int tag;
- const char *str;
- } mips_dtags[] =
- {
- { DT_MIPS_RLD_VERSION, "MIPS_RLD_VERSION" },
- { DT_MIPS_TIME_STAMP, "MIPS_TIME_STAMP" },
- { DT_MIPS_ICHECKSUM, "MIPS_ICHECKSUM" },
- { DT_MIPS_IVERSION, "MIPS_IVERSION" },
- { DT_MIPS_FLAGS, "MIPS_FLAGS" },
- { DT_MIPS_BASE_ADDRESS, "MIPS_BASE_ADDRESS" },
- { DT_MIPS_MSYM, "MIPS_MSYM" },
- { DT_MIPS_CONFLICT, "MIPS_CONFLICT" },
- { DT_MIPS_LIBLIST, "MIPS_LIBLIST" },
- { DT_MIPS_LOCAL_GOTNO, "MIPS_LOCAL_GOTNO" },
- { DT_MIPS_CONFLICTNO, "MIPS_CONFLICTNO" },
- { DT_MIPS_LIBLISTNO, "MIPS_LIBLISTNO" },
- { DT_MIPS_SYMTABNO, "MIPS_SYMTABNO" },
- { DT_MIPS_UNREFEXTNO, "MIPS_UNREFEXTNO" },
- { DT_MIPS_GOTSYM, "MIPS_GOTSYM" },
- { DT_MIPS_HIPAGENO, "MIPS_HIPAGENO" },
- { DT_MIPS_RLD_MAP, "MIPS_RLD_MAP" },
- { DT_MIPS_DELTA_CLASS, "MIPS_DELTA_CLASS" },
- { DT_MIPS_DELTA_CLASS_NO, "MIPS_DELTA_CLASS_NO" },
- { DT_MIPS_DELTA_INSTANCE, "MIPS_DELTA_INSTANCE" },
- { DT_MIPS_DELTA_INSTANCE_NO, "MIPS_DELTA_INSTANCE_NO" },
- { DT_MIPS_DELTA_RELOC, "MIPS_DELTA_RELOC" },
- { DT_MIPS_DELTA_RELOC_NO, "MIPS_DELTA_RELOC_NO" },
- { DT_MIPS_DELTA_SYM, "MIPS_DELTA_SYM" },
- { DT_MIPS_DELTA_SYM_NO, "MIPS_DELTA_SYM_NO" },
- { DT_MIPS_DELTA_CLASSSYM, "MIPS_DELTA_CLASSSYM" },
- { DT_MIPS_DELTA_CLASSSYM_NO, "MIPS_DELTA_CLASSSYM_NO" },
- { DT_MIPS_CXX_FLAGS, "MIPS_CXX_FLAGS" },
- { DT_MIPS_PIXIE_INIT, "MIPS_PIXIE_INIT" },
- { DT_MIPS_SYMBOL_LIB, "MIPS_SYMBOL_LIB" },
- { DT_MIPS_LOCALPAGE_GOTIDX, "MIPS_LOCALPAGE_GOTIDX" },
- { DT_MIPS_LOCAL_GOTIDX, "MIPS_LOCAL_GOTIDX" },
- { DT_MIPS_HIDDEN_GOTIDX, "MIPS_HIDDEN_GOTIDX" },
- { DT_MIPS_PROTECTED_GOTIDX, "MIPS_PROTECTED_GOTIDX" },
- { DT_MIPS_OPTIONS, "MIPS_OPTIONS" },
- { DT_MIPS_INTERFACE, "MIPS_INTERFACE" },
- { DT_MIPS_DYNSTR_ALIGN, "MIPS_DYNSTR_ALIGN" },
- { DT_MIPS_INTERFACE_SIZE, "MIPS_INTERFACE_SIZE" },
- { DT_MIPS_RLD_TEXT_RESOLVE_ADDR, "MIPS_RLD_TEXT_RESOLVE_ADDR" },
- { DT_MIPS_PERF_SUFFIX, "MIPS_PERF_SUFFIX" },
- { DT_MIPS_COMPACT_SIZE, "MIPS_COMPACT_SIZE" },
- { DT_MIPS_GP_VALUE, "MIPS_GP_VALUE" },
- { DT_MIPS_AUX_DYNAMIC, "MIPS_AUX_DYNAMIC" },
- };
-#define ndtags (sizeof (mips_dtags) / sizeof (mips_dtags[0]))
- size_t cnt;
-
- for (cnt = 0; cnt < ndtags; ++cnt)
- if (tag == mips_dtags[cnt].tag)
- return mips_dtags[cnt].str;
-
- /* We don't know this dynamic tag. */
- return NULL;
-}
diff --git a/elfutils/libebl/ppc64_init.c b/elfutils/libebl/ppc64_init.c
index 6cbe3a51..c8235bb1 100644
--- a/elfutils/libebl/ppc64_init.c
+++ b/elfutils/libebl/ppc64_init.c
@@ -19,7 +19,7 @@
#include <libebl_ppc64.h>
-int
+const char *
ppc64_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,7 +28,7 @@ ppc64_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "PowerPC 64-bit";
@@ -37,7 +37,11 @@ ppc64_init (elf, machine, eh, ehlen)
eh->reloc_valid_use = ppc64_reloc_valid_use;
eh->reloc_simple_type = ppc64_reloc_simple_type;
eh->dynamic_tag_name = ppc64_dynamic_tag_name;
+ eh->dynamic_tag_check = ppc64_dynamic_tag_check;
+ eh->copy_reloc_p = ppc64_copy_reloc_p;
+ eh->check_special_symbol = ppc64_check_special_symbol;
+ eh->bss_plt_p = ppc64_bss_plt_p;
eh->destr = ppc64_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/ppc64_symbol.c b/elfutils/libebl/ppc64_symbol.c
index 4914e523..7222ae40 100644
--- a/elfutils/libebl/ppc64_symbol.c
+++ b/elfutils/libebl/ppc64_symbol.c
@@ -19,6 +19,7 @@
#include <assert.h>
#include <elf.h>
#include <stddef.h>
+#include <string.h>
#include <libebl_ppc64.h>
@@ -226,3 +227,44 @@ ppc64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
}
return NULL;
}
+
+
+bool
+ppc64_dynamic_tag_check (int64_t tag)
+{
+ return (tag == DT_PPC64_GLINK
+ || tag == DT_PPC64_OPD
+ || tag == DT_PPC64_OPDSZ);
+}
+
+
+/* Check whether given relocation is a copy relocation. */
+bool
+ppc64_copy_reloc_p (int reloc)
+{
+ return reloc == R_PPC64_COPY;
+}
+
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+ normal checks. */
+bool
+ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym __attribute__ ((unused)),
+ const char *name __attribute__ ((unused)),
+ const GElf_Shdr *destshdr)
+{
+ const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+ if (sname == NULL)
+ return false;
+ return strcmp (sname, ".opd") == 0;
+}
+
+
+/* Check if backend uses a bss PLT in this file. */
+bool
+ppc64_bss_plt_p (Elf *elf __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)))
+{
+ return true;
+}
diff --git a/elfutils/libebl/ppc_init.c b/elfutils/libebl/ppc_init.c
index c7866613..d76b1b13 100644
--- a/elfutils/libebl/ppc_init.c
+++ b/elfutils/libebl/ppc_init.c
@@ -19,7 +19,7 @@
#include <libebl_ppc.h>
-int
+const char *
ppc_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,7 +28,7 @@ ppc_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "PowerPC";
@@ -36,7 +36,12 @@ ppc_init (elf, machine, eh, ehlen)
eh->reloc_type_check = ppc_reloc_type_check;
eh->reloc_valid_use = ppc_reloc_valid_use;
eh->reloc_simple_type = ppc_reloc_simple_type;
+ eh->dynamic_tag_name = ppc_dynamic_tag_name;
+ eh->dynamic_tag_check = ppc_dynamic_tag_check;
+ eh->copy_reloc_p = ppc_copy_reloc_p;
+ eh->check_special_symbol = ppc_check_special_symbol;
+ eh->bss_plt_p = ppc_bss_plt_p;
eh->destr = ppc_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/ppc_symbol.c b/elfutils/libebl/ppc_symbol.c
index cd75d93d..d83da9ec 100644
--- a/elfutils/libebl/ppc_symbol.c
+++ b/elfutils/libebl/ppc_symbol.c
@@ -19,6 +19,7 @@
#include <assert.h>
#include <elf.h>
#include <stddef.h>
+#include <string.h>
#include <libebl_ppc.h>
@@ -103,8 +104,14 @@ static struct
[R_PPC_GOT_DTPREL16] = { "R_PPC_GOT_DTPREL16", exec },
[R_PPC_GOT_DTPREL16_LO] = { "R_PPC_GOT_DTPREL16_LO", exec },
[R_PPC_GOT_DTPREL16_HI] = { "R_PPC_GOT_DTPREL16_HI", exec },
- [R_PPC_GOT_DTPREL16_HA] = { "R_PPC_GOT_DTPREL16_HA", exec }
+ [R_PPC_GOT_DTPREL16_HA] = { "R_PPC_GOT_DTPREL16_HA", exec },
+ [R_PPC_REL16] = { "R_PPC_REL16", rel },
+ [R_PPC_REL16_LO] = { "R_PPC_REL16_LO", rel },
+ [R_PPC_REL16_HI] = { "R_PPC_REL16_HI", rel },
+ [R_PPC_REL16_HA] = { "R_PPC_REL16_HA", rel },
};
+#define nreloc_map_table \
+ (sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))
/* Determine relocation type string for PPC. */
@@ -112,7 +119,7 @@ const char *
ppc_reloc_type_name (int type, char *buf __attribute__ ((unused)),
size_t len __attribute__ ((unused)))
{
- if (type < 0 || type >= R_PPC_NUM)
+ if (type < 0 || (size_t) type >= nreloc_map_table)
return NULL;
return reloc_map_table[type].name;
@@ -123,7 +130,7 @@ ppc_reloc_type_name (int type, char *buf __attribute__ ((unused)),
bool
ppc_reloc_type_check (int type)
{
- return (type >= R_PPC_NONE && type < R_PPC_NUM
+ return (type >= R_PPC_NONE && (size_t) type < nreloc_map_table
&& reloc_map_table[type].name != NULL) ? true : false;
}
@@ -165,3 +172,112 @@ ppc_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
return ELF_T_NUM;
}
}
+
+
+const char *
+ppc_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_PPC_GOT:
+ return "PPC_GOT";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+bool
+ppc_dynamic_tag_check (int64_t tag)
+{
+ return tag == DT_PPC_GOT;
+}
+
+
+/* Check whether given relocation is a copy relocation. */
+bool
+ppc_copy_reloc_p (int reloc)
+{
+ return reloc == R_PPC_COPY;
+}
+
+
+/* Look for DT_PPC_GOT. */
+static bool
+find_dyn_got (Elf *elf, GElf_Ehdr *ehdr, GElf_Addr *addr)
+{
+ for (int i = 0; i < ehdr->e_phnum; ++i)
+ {
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+ if (phdr == NULL || phdr->p_type != PT_DYNAMIC)
+ continue;
+
+ Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL)
+ for (unsigned int j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
+ {
+ GElf_Dyn dyn_mem;
+ GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
+ if (dyn != NULL && dyn->d_tag == DT_PPC_GOT)
+ {
+ *addr = dyn->d_un.d_ptr;
+ return true;
+ }
+ }
+
+ /* There is only one PT_DYNAMIC entry. */
+ break;
+ }
+
+ return false;
+}
+
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+ normal checks. */
+bool
+ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym,
+ const char *name, const GElf_Shdr *destshdr)
+{
+ if (name == NULL)
+ return false;
+
+ if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+ {
+ GElf_Addr gotaddr;
+ if (find_dyn_got (elf, ehdr, &gotaddr))
+ return sym->st_value == gotaddr;
+ return sym->st_value == destshdr->sh_addr + 4;
+ }
+
+ const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+ if (sname == NULL)
+ return false;
+
+ if (strcmp (name, "_SDA_BASE_") == 0)
+ return (strcmp (sname, ".sdata") == 0
+ && sym->st_value == destshdr->sh_addr + 0x8000
+ && sym->st_size == 0);
+
+ if (strcmp (name, "_SDA2_BASE_") == 0)
+ return (strcmp (sname, ".sdata2") == 0
+ && sym->st_value == destshdr->sh_addr + 0x8000
+ && sym->st_size == 0);
+
+ return false;
+}
+
+
+/* Check if backend uses a bss PLT in this file. */
+bool
+ppc_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr)
+{
+ GElf_Addr addr;
+ return ! find_dyn_got (elf, ehdr, &addr);
+}
diff --git a/elfutils/libebl/sh_init.c b/elfutils/libebl/sh_init.c
index 85f2592b..bb6c9040 100644
--- a/elfutils/libebl/sh_init.c
+++ b/elfutils/libebl/sh_init.c
@@ -19,7 +19,7 @@
#include <libebl_sh.h>
-int
+const char *
sh_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,12 +28,13 @@ sh_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "Hitachi SH";
eh->reloc_type_name = sh_reloc_type_name;
+ eh->copy_reloc_p = sh_copy_reloc_p;
eh->destr = sh_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/sh_symbol.c b/elfutils/libebl/sh_symbol.c
index e28741d2..e24fff15 100644
--- a/elfutils/libebl/sh_symbol.c
+++ b/elfutils/libebl/sh_symbol.c
@@ -90,3 +90,10 @@ sh_reloc_type_name (int type, char *buf __attribute__ ((unused)),
return NULL;
}
+
+/* Check whether given relocation is a copy relocation. */
+bool
+sh_copy_reloc_p (int reloc)
+{
+ return reloc == R_SH_COPY;
+}
diff --git a/elfutils/libebl/sparc_init.c b/elfutils/libebl/sparc_init.c
index d9e5a69f..ac461a10 100644
--- a/elfutils/libebl/sparc_init.c
+++ b/elfutils/libebl/sparc_init.c
@@ -18,7 +18,7 @@
#include <libebl_sparc.h>
-int
+const char *
sparc_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -27,7 +27,7 @@ sparc_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
if (machine == EM_SPARCV9)
@@ -39,7 +39,8 @@ sparc_init (elf, machine, eh, ehlen)
eh->reloc_type_name = sparc_reloc_type_name;
eh->reloc_type_check = sparc_reloc_type_check;
//eh->core_note = sparc_core_note;
+ eh->copy_reloc_p = sparc_copy_reloc_p;
eh->destr = sparc_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/sparc_symbol.c b/elfutils/libebl/sparc_symbol.c
index dbb942b5..f33ed537 100644
--- a/elfutils/libebl/sparc_symbol.c
+++ b/elfutils/libebl/sparc_symbol.c
@@ -140,3 +140,10 @@ sparc_reloc_type_check (int type)
return (type >= R_SPARC_NONE && type < R_SPARC_NUM
&& reloc_map_table[type] != NULL) ? true : false;
}
+
+/* Check whether given relocation is a copy relocation. */
+bool
+sparc_copy_reloc_p (int reloc)
+{
+ return reloc == R_SPARC_COPY;
+}
diff --git a/elfutils/libebl/x86_64_corenote.c b/elfutils/libebl/x86_64_corenote.c
new file mode 100644
index 00000000..0ee7ceae
--- /dev/null
+++ b/elfutils/libebl/x86_64_corenote.c
@@ -0,0 +1,171 @@
+/* x86-64 specific core note handling.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#include <libebl_x86_64.h>
+
+
+/* We cannot include <sys/procfs.h> since the definition would be for
+ the host platform and not always x86-64 as required here. */
+struct elf_prstatus
+ {
+ struct
+ {
+ int32_t si_signo; /* Signal number. */
+ int32_t si_code; /* Extra code. */
+ int32_t si_errno; /* Errno. */
+ } pr_info; /* Info associated with signal. */
+ int16_t pr_cursig; /* Current signal. */
+ uint64_t pr_sigpend; /* Set of pending signals. */
+ uint64_t pr_sighold; /* Set of held signals. */
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ struct x86_64_timeval
+ {
+ int64_t tv_sec;
+ int32_t tv_usec;
+ } pr_utime; /* User time. */
+ struct x86_64_timeval pr_stime; /* System time. */
+ struct x86_64_timeval pr_cutime; /* Cumulative user time. */
+ struct x86_64_timeval pr_cstime; /* Cumulative system time. */
+ uint64_t pr_reg[27]; /* GP registers. */
+ int32_t pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ uint64_t pr_flag; /* Flags. */
+ uint32_t pr_uid;
+ uint32_t pr_gid;
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[80]; /* Initial part of arg list. */
+ };
+
+
+bool
+x86_64_core_note (name, type, descsz, desc)
+ const char *name __attribute__ ((unused));
+ uint32_t type;
+ uint32_t descsz;
+ const char *desc;
+{
+ bool result = false;
+
+ switch (type)
+ {
+ case NT_PRSTATUS:
+ if (descsz < sizeof (struct elf_prstatus))
+ /* Not enough data. */
+ break;
+
+ struct elf_prstatus *stat = (struct elf_prstatus *) desc;
+
+ printf (" SIGINFO: signo: %" PRId32 ", code = %" PRId32
+ ", errno = %" PRId32 "\n"
+ " signal: %" PRId16 ", pending: %#08" PRIx64 ", holding: %#08"
+ PRIx64 "\n"
+ " pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
+ ", sid = %" PRId32 "\n"
+ " utime: %6" PRId64 ".%06" PRId32
+ "s, stime: %6" PRId64 ".%06" PRId32 "s\n"
+ " cutime: %6" PRId64 ".%06" PRId32
+ "s, cstime: %6" PRId64 ".%06" PRId32 "s\n"
+ " rax: %016" PRIx64 " rbx: %016" PRIx64 "\n"
+ " rcx: %016" PRIx64 " rdx: %016" PRIx64 "\n"
+ " rsi: %016" PRIx64 " rdi: %016" PRIx64 "\n"
+ " rbp: %016" PRIx64 " rsp: %016" PRIx64 "\n"
+ " r8: %016" PRIx64 " r9: %016" PRIx64 "\n"
+ " r10: %016" PRIx64 " r11: %016" PRIx64 "\n"
+ " r12: %016" PRIx64 " r13: %016" PRIx64 "\n"
+ " r14: %016" PRIx64 " r15: %016" PRIx64 "\n"
+ " rip: %016" PRIx64 " eflags: %08" PRIx64 "\n"
+ " original rax: %016" PRIx64 "\n"
+ " cs: %04" PRIx64 " ds: %04" PRIx64 " es: %04" PRIx64
+ " ss: %04" PRIx64 "\n"
+ " fs: %04" PRIx64 " fs_base: %016" PRIx64
+ " gs: %04" PRIx64 " gs_base: %016" PRIx64 "\n\n",
+ stat->pr_info. si_signo,
+ stat->pr_info. si_code,
+ stat->pr_info. si_errno,
+ stat->pr_cursig,
+ stat->pr_sigpend, stat->pr_sighold,
+ stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
+ stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
+ stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
+ stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
+ stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
+ stat->pr_reg[10], stat->pr_reg[5], stat->pr_reg[11],
+ stat->pr_reg[12], stat->pr_reg[13], stat->pr_reg[14],
+ stat->pr_reg[4], stat->pr_reg[10], stat->pr_reg[9],
+ stat->pr_reg[7], stat->pr_reg[6], stat->pr_reg[5],
+ stat->pr_reg[3], stat->pr_reg[2], stat->pr_reg[1],
+ stat->pr_reg[0], stat->pr_reg[16], stat->pr_reg[18],
+ stat->pr_reg[15], stat->pr_reg[17], stat->pr_reg[23],
+ stat->pr_reg[24], stat->pr_reg[20],
+ stat->pr_reg[25], stat->pr_reg[21],
+ stat->pr_reg[26], stat->pr_reg[22]);
+
+ /* We handled this entry. */
+ result = true;
+ break;
+
+ case NT_PRPSINFO:
+ if (descsz < sizeof (struct elf_prpsinfo))
+ /* Not enough data. */
+ break;
+
+ struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
+
+ printf (" state: %c (%hhd), zombie: %hhd, nice: %hhd\n"
+ " flags: %08" PRIx64 " uid: %" PRIu32 " gid: %" PRIu32 "\n"
+ " pid: %" PRId32 " ppid: %" PRId32 " pgrp: %" PRId32
+ " sid: %" PRId32 "\n"
+ " fname: %.16s\n"
+ " args: %.80s\n\n",
+ info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
+ info->pr_flag, info->pr_uid, info->pr_gid,
+ info->pr_pid, info->pr_ppid, info->pr_pgrp, info->pr_sid,
+ info->pr_fname, info->pr_psargs);
+
+ /* We handled this entry. */
+ result = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
diff --git a/elfutils/libebl/x86_64_init.c b/elfutils/libebl/x86_64_init.c
index 45a08774..655a67fb 100644
--- a/elfutils/libebl/x86_64_init.c
+++ b/elfutils/libebl/x86_64_init.c
@@ -19,7 +19,7 @@
#include <libebl_x86_64.h>
-int
+const char *
x86_64_init (elf, machine, eh, ehlen)
Elf *elf __attribute__ ((unused));
GElf_Half machine __attribute__ ((unused));
@@ -28,7 +28,7 @@ x86_64_init (elf, machine, eh, ehlen)
{
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
- return 1;
+ return NULL;
/* We handle it. */
eh->name = "AMD x86-64";
@@ -36,8 +36,9 @@ x86_64_init (elf, machine, eh, ehlen)
eh->reloc_type_check = x86_64_reloc_type_check;
eh->reloc_valid_use = x86_64_reloc_valid_use;
eh->reloc_simple_type = x86_64_reloc_simple_type;
- //eh->core_note = i386_core_note;
+ eh->core_note = x86_64_core_note;
+ eh->copy_reloc_p = x86_64_copy_reloc_p;
eh->destr = x86_64_destr;
- return 0;
+ return MODVERSION;
}
diff --git a/elfutils/libebl/x86_64_symbol.c b/elfutils/libebl/x86_64_symbol.c
index b8c13b1e..38d357cb 100644
--- a/elfutils/libebl/x86_64_symbol.c
+++ b/elfutils/libebl/x86_64_symbol.c
@@ -127,3 +127,10 @@ x86_64_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
return ELF_T_NUM;
}
}
+
+/* Check whether given relocation is a copy relocation. */
+bool
+x86_64_copy_reloc_p (int reloc)
+{
+ return reloc == R_X86_64_COPY;
+}
diff --git a/elfutils/libelf-po/libelf.pot b/elfutils/libelf-po/libelf.pot
index f0cd7572..0aa50281 100644
--- a/elfutils/libelf-po/libelf.pot
+++ b/elfutils/libelf-po/libelf.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2005-05-09 22:10-0700\n"
+"POT-Creation-Date: 2005-08-24 14:41-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -175,3 +175,7 @@ msgstr ""
#: libelf/elf_error.c:245
msgid "file has no program header"
msgstr ""
+
+#: libelf/elf_error.c:250
+msgid "invalid offset"
+msgstr ""
diff --git a/elfutils/libelf/ChangeLog b/elfutils/libelf/ChangeLog
index 6745d276..5c68569e 100644
--- a/elfutils/libelf/ChangeLog
+++ b/elfutils/libelf/ChangeLog
@@ -1,3 +1,71 @@
+2005-08-15 Ulrich Drepper <drepper@redhat.com>
+
+ * elf_begin.c (__libelf_next_arhdr): Use TEMP_FAILURE_RETRY.
+
+ * Makefile (libelf_a_SOURCES): Add elf_getaroff.c.
+ * libelf.map: Export elf_getaroff.
+ * libelf.h: Declare elf_getaroff.
+ * elf_getaroff.c: New file.
+
+2005-08-13 Ulrich Drepper <drepper@redhat.com>
+
+ * elf_begin.c (get_shnum): Optimize memory handling. Always read from
+ mapped file if available. Fix access to 64-bit sh_size. Recognize
+ overflow.
+ (file_read_elf): Likewise.
+
+2005-08-12 Roland McGrath <roland@redhat.com>
+
+ * elf32_offscn.c: Do not match empty sections at OFFSET unless
+ there are no nonempty sections at that offset.
+
+2005-08-07 Ulrich Drepper <drepper@redhat.com>
+
+ * elf.h: Update from glibc.
+
+2005-08-06 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (AM_CFLAGS): Add -fpic when BUILD_STATIC.
+
+2005-08-03 Ulrich Drepper <drepper@redhat.com>
+
+ * libelf.map: Move elf32_offscn, elf64_offscn, and gelf_offscn in
+ new version ELFUTILS_1.1.1.
+
+2005-08-02 Ulrich Drepper <drepper@redhat.com>
+
+ * elf_error.c: Add handling of ELF_E_INVALID_OFFSET.
+ * elf32_offscn.c: New file.
+ * elf64_offscn.c: New file.
+ * gelf_offscn.c: New file.
+ * Makefile.am (libelf_a_SOURCES): Add elf32_offscn.c, elf64_offscn.c,
+ and gelf_offscn.c.
+ * libelf.sym: Export new symbols.
+
+2005-07-23 Ulrich Drepper <drepper@redhat.com>
+
+ * elf-knowledge.h (SECTION_STRIP_P): Don't handle removal of debug
+ sections here anymore.
+ * elf32_checksum.c: Adjust for change in SECTION_STRIP_P interface.
+
+ * elf_update.c (elf_update): Get write lock, not read lock.
+
+ * elf32_updatenull.c (updatenull): Get section headers if necessary
+ and possible.
+
+2005-07-22 Ulrich Drepper <drepper@redhat.com>
+
+ * elf32_updatenull.c (updatenull): If program header hasn't been loaded
+ yet, try to do it now.
+ Don't unnecessarily update overflow of section count in zeroth section
+ sh_size field.
+ If section content hasn't been read yet, do it before looking for the
+ block size. If no section data present, infer size of section header.
+
+2005-05-11 Ulrich Drepper <drepper@redhat.com>
+
+ * elf.h: Update again.
+
2005-05-09 Ulrich Drepper <drepper@redhat.com>
* elf.h: Update from glibc.
diff --git a/elfutils/libelf/Makefile.am b/elfutils/libelf/Makefile.am
index cf581902..28d0d6ed 100644
--- a/elfutils/libelf/Makefile.am
+++ b/elfutils/libelf/Makefile.am
@@ -17,10 +17,13 @@
##
DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H
if MUDFLAP
-AM_CFLAGS = -fpic -fmudflap
+AM_CFLAGS = -fmudflap
else
AM_CFLAGS =
endif
+if BUILD_STATIC
+AM_CFLAGS += -fpic
+endif
AM_CFLAGS += -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 -std=gnu99 \
$($(*F)_CFLAGS)
INCLUDES = -I$(srcdir) -I$(top_srcdir)/lib -I..
@@ -79,7 +82,9 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
gelf_rawchunk.c gelf_freechunk.c \
libelf_crc32.c libelf_next_prime.c \
elf_clone.c \
- gelf_getlib.c gelf_update_lib.c
+ gelf_getlib.c gelf_update_lib.c \
+ elf32_offscn.c elf64_offscn.c gelf_offscn.c \
+ elf_getaroff.c
if !MUDFLAP
libelf_pic_a_SOURCES =
diff --git a/elfutils/libelf/Makefile.in b/elfutils/libelf/Makefile.in
index 3b391784..90182919 100644
--- a/elfutils/libelf/Makefile.in
+++ b/elfutils/libelf/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,8 +16,6 @@
-SOURCES = $(libelf_a_SOURCES) $(libelf_pic_a_SOURCES) $(libelf_so_SOURCES)
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -40,6 +38,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@BUILD_STATIC_TRUE@am__append_1 = -fpic
@MUDFLAP_FALSE@noinst_PROGRAMS = $(am__EXEEXT_1)
@MUDFLAP_TRUE@am_libelf_pic_a_OBJECTS =
subdir = libelf
@@ -117,7 +116,9 @@ am_libelf_a_OBJECTS = elf_version.$(OBJEXT) elf_hash.$(OBJEXT) \
gelf_rawchunk.$(OBJEXT) gelf_freechunk.$(OBJEXT) \
libelf_crc32.$(OBJEXT) libelf_next_prime.$(OBJEXT) \
elf_clone.$(OBJEXT) gelf_getlib.$(OBJEXT) \
- gelf_update_lib.$(OBJEXT)
+ gelf_update_lib.$(OBJEXT) elf32_offscn.$(OBJEXT) \
+ elf64_offscn.$(OBJEXT) gelf_offscn.$(OBJEXT) \
+ elf_getaroff.$(OBJEXT)
libelf_a_OBJECTS = $(am_libelf_a_OBJECTS)
libelf_pic_a_AR = $(AR) $(ARFLAGS)
libelf_pic_a_LIBADD =
@@ -152,6 +153,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -165,6 +168,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -173,12 +178,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -240,10 +247,11 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Wshadow -Werror -Wunused -Wextra \
-@MUDFLAP_FALSE@ -Wformat=2 -std=gnu99 $($(*F)_CFLAGS)
-@MUDFLAP_TRUE@AM_CFLAGS = -fpic -fmudflap -Wall -Wshadow -Werror \
-@MUDFLAP_TRUE@ -Wunused -Wextra -Wformat=2 -std=gnu99 \
+@MUDFLAP_FALSE@AM_CFLAGS = $(am__append_1) -Wall -Wshadow -Werror \
+@MUDFLAP_FALSE@ -Wunused -Wextra -Wformat=2 -std=gnu99 \
+@MUDFLAP_FALSE@ $($(*F)_CFLAGS)
+@MUDFLAP_TRUE@AM_CFLAGS = -fmudflap $(am__append_1) -Wall -Wshadow \
+@MUDFLAP_TRUE@ -Werror -Wunused -Wextra -Wformat=2 -std=gnu99 \
@MUDFLAP_TRUE@ $($(*F)_CFLAGS)
INCLUDES = -I$(srcdir) -I$(top_srcdir)/lib -I..
GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
@@ -293,7 +301,9 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
gelf_rawchunk.c gelf_freechunk.c \
libelf_crc32.c libelf_next_prime.c \
elf_clone.c \
- gelf_getlib.c gelf_update_lib.c
+ gelf_getlib.c gelf_update_lib.c \
+ elf32_offscn.c elf64_offscn.c gelf_offscn.c \
+ elf_getaroff.c
@MUDFLAP_FALSE@libelf_pic_a_SOURCES =
@MUDFLAP_FALSE@am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
@@ -396,6 +406,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getshdr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_newehdr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_newphdr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_offscn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_updatefile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_updatenull.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_xlatetof.Po@am__quote@
@@ -407,6 +418,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getshdr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_newehdr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_newphdr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_offscn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_updatefile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_updatenull.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_xlatetof.Po@am__quote@
@@ -424,6 +436,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagscn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagshdr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getarhdr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getaroff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getarsym.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getbase.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getdata.Po@am__quote@
@@ -468,6 +481,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getversym.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_newehdr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_newphdr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_offscn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_rawchunk.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_dyn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_ehdr.Po@am__quote@
diff --git a/elfutils/libelf/elf-knowledge.h b/elfutils/libelf/elf-knowledge.h
index c44e37f7..b92fd8a2 100644
--- a/elfutils/libelf/elf-knowledge.h
+++ b/elfutils/libelf/elf-knowledge.h
@@ -1,5 +1,5 @@
/* Accumulation of various pieces of knowledge about ELF.
- Copyright (C) 2000, 2001, 2002, 2003 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
@@ -18,32 +18,21 @@
#ifndef _ELF_KNOWLEDGE_H
#define _ELF_KNOWLEDGE_H 1
+#include <stdbool.h>
+
/* Test whether a section can be stripped or not. */
-#define SECTION_STRIP_P(ebl, elf, ehdr, shdr, name, remove_comment, remove_debug) \
- (/* Sections which are allocated are not removed. */ \
- ((shdr)->sh_flags & SHF_ALLOC) == 0 \
+#define SECTION_STRIP_P(shdr, name, remove_comment) \
+ /* Sections which are allocated are not removed. */ \
+ (((shdr)->sh_flags & SHF_ALLOC) == 0 \
/* We never remove .note sections. */ \
&& (shdr)->sh_type != SHT_NOTE \
- /* If only debug information should be removed check the name. There \
- is unfortunately no way. */ \
- && (!remove_debug \
- || ebl_debugscn_p (ebl, name) \
- || (((shdr)->sh_type == SHT_RELA || (shdr)->sh_type == SHT_REL) \
- && ({ Elf_Scn *scn_l = elf_getscn (elf, (shdr)->sh_info); \
- GElf_Shdr shdr_mem_l; \
- GElf_Shdr *shdr_l = gelf_getshdr (scn_l, &shdr_mem_l); \
- const char *s_l; \
- shdr_l != NULL \
- && (s_l = elf_strptr (elf, \
- ((GElf_Ehdr *) (ehdr))->e_shstrndx, \
- shdr_l->sh_name)) != NULL \
- && ebl_debugscn_p (ebl, s_l); }))) \
- && ((shdr)->sh_type != SHT_PROGBITS \
- /* Never remove .gnu.warning.* sections. */ \
+ && (((shdr)->sh_type) != SHT_PROGBITS \
+ /* Never remove .gnu.warning.* sections. */ \
|| (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) != 0 \
- /* We remove .comment sections only if explicitly told to do so. */ \
- && ((remove_comment) || strcmp (name, ".comment") != 0))) \
+ /* We remove .comment sections only if explicitly told to do so. */\
+ && (remove_comment \
+ || strcmp (name, ".comment") != 0))) \
/* So far we do not remove any of the non-standard sections. \
XXX Maybe in future. */ \
&& (shdr)->sh_type < SHT_NUM)
diff --git a/elfutils/libelf/elf.h b/elfutils/libelf/elf.h
index 8a9f7fd4..ef9e27cc 100644
--- a/elfutils/libelf/elf.h
+++ b/elfutils/libelf/elf.h
@@ -899,23 +899,25 @@ typedef struct
typedef struct
{
- int a_type; /* Entry type */
+ uint32_t a_type; /* Entry type */
union
{
- long int a_val; /* Integer value */
- void *a_ptr; /* Pointer value */
- void (*a_fcn) (void); /* Function pointer value */
+ uint32_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
} a_un;
} Elf32_auxv_t;
typedef struct
{
- long int a_type; /* Entry type */
+ uint64_t a_type; /* Entry type */
union
{
- long int a_val; /* Integer value */
- void *a_ptr; /* Pointer value */
- void (*a_fcn) (void); /* Function pointer value */
+ uint64_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
} a_un;
} Elf64_auxv_t;
@@ -1864,6 +1866,9 @@ typedef Elf32_Addr Elf32_Conflict;
#define LITUSE_ALPHA_TLS_GD 4
#define LITUSE_ALPHA_TLS_LDM 5
+/* Legal values for d_tag of Elf64_Dyn. */
+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
+#define DT_ALPHA_NUM 1
/* PowerPC specific declarations */
@@ -1974,10 +1979,19 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
+/* GNU relocs used in PIC code sequences. */
+#define R_PPC_REL16 249 /* word32 (sym-.) */
+#define R_PPC_REL16_LO 250 /* half16 (sym-.)@l */
+#define R_PPC_REL16_HI 251 /* half16 (sym-.)@h */
+#define R_PPC_REL16_HA 252 /* half16 (sym-.)@ha */
+
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
+/* PowerPC specific values for the Dyn d_tag field. */
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
diff --git a/elfutils/libelf/elf32_checksum.c b/elfutils/libelf/elf32_checksum.c
index 580f27c3..a54ebbc4 100644
--- a/elfutils/libelf/elf32_checksum.c
+++ b/elfutils/libelf/elf32_checksum.c
@@ -88,9 +88,9 @@ elfw2(LIBELFBITS,checksum) (elf)
return -1l;
}
- if (SECTION_STRIP_P (NULL, NULL, NULL, shdr,
+ if (SECTION_STRIP_P (shdr,
INTUSE(elf_strptr) (elf, shstrndx, shdr->sh_name),
- true, false))
+ true))
/* The section can be stripped. Don't use it. */
continue;
diff --git a/elfutils/libelf/elf32_offscn.c b/elfutils/libelf/elf32_offscn.c
new file mode 100644
index 00000000..843f8b00
--- /dev/null
+++ b/elfutils/libelf/elf32_offscn.c
@@ -0,0 +1,80 @@
+/* Get section at specific index.
+ Copyright (C) 2005 Red Hat, Inc.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+Elf_Scn *
+elfw2(LIBELFBITS,offscn) (elf, offset)
+ Elf *elf;
+ ElfW2(LIBELFBITS,Off) offset;
+{
+ if (elf == NULL)
+ return NULL;
+
+ if (unlikely (elf->kind != ELF_K_ELF))
+ {
+ __libelf_seterrno (ELF_E_INVALID_HANDLE);
+ return NULL;
+ }
+
+ rwlock_rdlock (elf->lock);
+
+ Elf_Scn *result = NULL;
+
+ /* Find the section in the list. */
+ Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns;
+ while (1)
+ {
+ for (unsigned int i = 0; i < runp->cnt; ++i)
+ if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_offset == offset)
+ {
+ result = &runp->data[i];
+
+ /* If this section is empty, the following one has the same
+ sh_offset. We presume the caller is looking for a nonempty
+ section, so keep looking if this one is empty. */
+ if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0)
+ goto out;
+ }
+
+ runp = runp->next;
+ if (runp == NULL)
+ {
+ __libelf_seterrno (ELF_E_INVALID_OFFSET);
+ break;
+ }
+ }
+
+ out:
+ rwlock_unlock (elf->lock);
+
+ return result;
+}
+INTDEF(elfw2(LIBELFBITS,offscn))
diff --git a/elfutils/libelf/elf32_updatenull.c b/elfutils/libelf/elf32_updatenull.c
index 3bac9c11..ed7242b2 100644
--- a/elfutils/libelf/elf32_updatenull.c
+++ b/elfutils/libelf/elf32_updatenull.c
@@ -114,6 +114,9 @@ __elfw2(LIBELFBITS,updatenull) (Elf *elf, int *change_bop, size_t shnum)
off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
/* Set the program header position. */
+ if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL
+ && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN))
+ (void) INTUSE(elfw2(LIBELFBITS,getphdr)) (elf);
if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
{
/* Only executables or shared objects have a program header. */
@@ -153,16 +156,20 @@ __elfw2(LIBELFBITS,updatenull) (Elf *elf, int *change_bop, size_t shnum)
{
/* We have to fill in the number of sections in the header
of the zeroth section. */
- elf->state.ELFW(elf,LIBELFBITS).scns.data[0].shdr.ELFW(e,LIBELFBITS)->sh_size
- = shnum;
- elf->state.ELFW(elf,LIBELFBITS).scns.data[0].shdr_flags
- |= ELF_F_DIRTY;
- }
+ Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
+ update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
+ shnum, scn0->shdr_flags);
+ }
/* Go over all sections and find out how large they are. */
list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+ /* Load the section headers if necessary. This loads the
+ headers for all sections. */
+ if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL)
+ (void) INTUSE(elfw2(LIBELFBITS,getshdr)) (&list->data[1]);
+
do
{
for (size_t cnt = first == true; cnt < list->cnt; ++cnt)
@@ -222,6 +229,10 @@ __elfw2(LIBELFBITS,updatenull) (Elf *elf, int *change_bop, size_t shnum)
update_if_changed (shdr->sh_entsize, sh_entsize,
scn->shdr_flags);
+ if (scn->data_read == 0 && __libelf_set_rawdata (scn) != 0)
+ /* Something went wrong. The error value is already set. */
+ return -1;
+
/* Iterate over all data blocks. */
if (list->data[cnt].data_list_rear != NULL)
{
@@ -229,28 +240,33 @@ __elfw2(LIBELFBITS,updatenull) (Elf *elf, int *change_bop, size_t shnum)
while (dl != NULL)
{
- if (unlikely (dl->data.d.d_version == EV_NONE)
- || unlikely (dl->data.d.d_version >= EV_NUM))
+ Elf_Data *data = &dl->data.d;
+ if (dl == &scn->data_list && data->d_buf == NULL
+ && scn->rawdata.d.d_buf != NULL)
+ data = &scn->rawdata.d;
+
+ if (unlikely (data->d_version == EV_NONE)
+ || unlikely (data->d_version >= EV_NUM))
{
__libelf_seterrno (ELF_E_UNKNOWN_VERSION);
return -1;
}
- if (unlikely (! powerof2 (dl->data.d.d_align)))
+ if (unlikely (! powerof2 (data->d_align)))
{
__libelf_seterrno (ELF_E_INVALID_ALIGN);
return -1;
}
- sh_align = MAX (sh_align, dl->data.d.d_align);
+ sh_align = MAX (sh_align, data->d_align);
if (elf->flags & ELF_F_LAYOUT)
{
/* The user specified the offset and the size.
All we have to do is check whether this block
fits in the size specified for the section. */
- if (unlikely ((GElf_Word) (dl->data.d.d_off
- + dl->data.d.d_size)
+ if (unlikely ((GElf_Word) (data->d_off
+ + data->d_size)
> shdr->sh_size))
{
__libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
@@ -260,19 +276,22 @@ __elfw2(LIBELFBITS,updatenull) (Elf *elf, int *change_bop, size_t shnum)
else
{
/* Determine the padding. */
- offset = ((offset + dl->data.d.d_align - 1)
- & ~(dl->data.d.d_align - 1));
+ offset = ((offset + data->d_align - 1)
+ & ~(data->d_align - 1));
- update_if_changed (dl->data.d.d_off, offset,
- changed);
+ update_if_changed (data->d_off, offset, changed);
- offset += dl->data.d.d_size;
+ offset += data->d_size;
}
/* Next data block. */
dl = dl->next;
}
}
+ else
+ /* Get the size of the section from the raw data. If
+ none is available the value is zero. */
+ offset += scn->rawdata.d.d_size;
if (elf->flags & ELF_F_LAYOUT)
{
diff --git a/elfutils/libelf/elf64_offscn.c b/elfutils/libelf/elf64_offscn.c
new file mode 100644
index 00000000..5391a595
--- /dev/null
+++ b/elfutils/libelf/elf64_offscn.c
@@ -0,0 +1,19 @@
+/* Return program header table.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define LIBELFBITS 64
+#include "elf32_offscn.c"
diff --git a/elfutils/libelf/elf_begin.c b/elfutils/libelf/elf_begin.c
index 404cbe83..c4b33595 100644
--- a/elfutils/libelf/elf_begin.c
+++ b/elfutils/libelf/elf_begin.c
@@ -69,6 +69,11 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
Elf64_Ehdr *e64;
void *p;
} ehdr;
+ union
+ {
+ Elf32_Ehdr e32;
+ Elf64_Ehdr e64;
+ } ehdr_mem;
bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
/* Make the ELF header available. */
@@ -83,11 +88,17 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
/* We have to read the data from the file. */
size_t len = is32 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr);
- ehdr.p = alloca (len);
- /* Fill it. */
- if ((size_t) pread (fildes, ehdr.p, len, offset) != len)
- /* Failed reading. */
- return (size_t) -1l;
+ if (likely (map_address != NULL))
+ ehdr.p = memcpy (&ehdr_mem, (char *) map_address + offset, len);
+ else
+ {
+ /* Fill it. */
+ if ((size_t) TEMP_FAILURE_RETRY (pread (fildes, &ehdr_mem, len,
+ offset)) != len)
+ /* Failed reading. */
+ return (size_t) -1l;
+ ehdr.p = &ehdr_mem;
+ }
if (e_ident[EI_DATA] != MY_ELFDATA)
{
@@ -120,18 +131,27 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
|| (((size_t) ((char *) map_address + offset))
& (__alignof__ (Elf32_Ehdr) - 1)) == 0))
/* We can directly access the memory. */
- result = ((Elf32_Shdr *) ((char *) map_address
- + ehdr.e32->e_shoff
+ result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
+ offset))->sh_size;
else
{
Elf32_Word size;
- if (pread (fildes, &size, sizeof (Elf32_Word),
- offset + ehdr.e32->e_shoff
- + offsetof (Elf32_Shdr, sh_size))
- != sizeof (Elf32_Word))
- return (size_t) -1l;
+ if (likely (map_address != NULL))
+ /* gcc will optimize the memcpy to a simple memory
+ access while taking care of alignment issues. */
+ memcpy (&size, &((Elf32_Shdr *) ((char *) map_address
+ + ehdr.e32->e_shoff
+ + offset))->sh_size,
+ sizeof (Elf32_Word));
+ else
+ if (TEMP_FAILURE_RETRY (pread (fildes, &size,
+ sizeof (Elf32_Word),
+ offset + ehdr.e32->e_shoff
+ + offsetof (Elf32_Shdr,
+ sh_size)))
+ != sizeof (Elf32_Word))
+ return (size_t) -1l;
if (e_ident[EI_DATA] != MY_ELFDATA)
CONVERT (size);
@@ -151,29 +171,41 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
/* Cannot read the first section header. */
return (size_t) -1l;
+ Elf64_Xword size;
if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
&& (ALLOW_UNALIGNED
|| (((size_t) ((char *) map_address + offset))
& (__alignof__ (Elf64_Ehdr) - 1)) == 0))
/* We can directly access the memory. */
- result = ((Elf64_Shdr *) ((char *) map_address
- + ehdr.e64->e_shoff
- + offset))->sh_size;
+ size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
+ + offset))->sh_size;
else
{
- Elf64_Word size;
-
- if (pread (fildes, &size, sizeof (Elf64_Word),
- offset + ehdr.e64->e_shoff
- + offsetof (Elf64_Shdr, sh_size))
- != sizeof (Elf64_Word))
- return (size_t) -1l;
+ if (likely (map_address != NULL))
+ /* gcc will optimize the memcpy to a simple memory
+ access while taking care of alignment issues. */
+ memcpy (&size, &((Elf64_Shdr *) ((char *) map_address
+ + ehdr.e64->e_shoff
+ + offset))->sh_size,
+ sizeof (Elf64_Xword));
+ else
+ if (TEMP_FAILURE_RETRY (pread (fildes, &size,
+ sizeof (Elf64_Word),
+ offset + ehdr.e64->e_shoff
+ + offsetof (Elf64_Shdr,
+ sh_size)))
+ != sizeof (Elf64_Xword))
+ return (size_t) -1l;
if (e_ident[EI_DATA] != MY_ELFDATA)
CONVERT (size);
-
- result = size;
}
+
+ if (size > ~((GElf_Word) 0))
+ /* Invalid value, it is too large. */
+ return (size_t) -1l;
+
+ result = size;
}
}
@@ -188,6 +220,7 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
{
/* We only read the ELF header now. */
unsigned char *e_ident;
+ unsigned char e_ident_mem[EI_NIDENT];
size_t scncnt;
Elf *elf;
@@ -197,9 +230,10 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
e_ident = (unsigned char *) map_address + offset;
else
{
- e_ident = (unsigned char *) alloca (EI_NIDENT);
+ e_ident = e_ident_mem;
- if (pread (fildes, e_ident, EI_NIDENT, offset) != EI_NIDENT)
+ if (TEMP_FAILURE_RETRY (pread (fildes, e_ident, EI_NIDENT, offset))
+ != EI_NIDENT)
{
__libelf_seterrno (ELF_E_READ_ERROR);
return NULL;
@@ -280,14 +314,21 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
}
else
{
- /* Read the data. */
- if (pread (elf->fildes, &elf->state.elf32.ehdr_mem,
- sizeof (Elf32_Ehdr), offset) != sizeof (Elf32_Ehdr))
- {
- /* We must be able to read the ELF header. */
- __libelf_seterrno (ELF_E_INVALID_FILE);
- return NULL;
- }
+ if (likely (map_address != NULL))
+ /* Copy the data. */
+ memcpy (&elf->state.elf32.ehdr_mem,
+ (char *) map_address + offset, sizeof (Elf32_Ehdr));
+ else
+ /* Read the data. */
+ if (TEMP_FAILURE_RETRY (pread (elf->fildes,
+ &elf->state.elf32.ehdr_mem,
+ sizeof (Elf32_Ehdr), offset))
+ != sizeof (Elf32_Ehdr))
+ {
+ /* We must be able to read the ELF header. */
+ __libelf_seterrno (ELF_E_INVALID_FILE);
+ return NULL;
+ }
if (e_ident[EI_DATA] != MY_ELFDATA)
{
@@ -365,9 +406,16 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
}
else
{
- /* Read the data. */
- if (pread (elf->fildes, &elf->state.elf64.ehdr_mem,
- sizeof (Elf64_Ehdr), offset) != sizeof (Elf64_Ehdr))
+ if (likely (map_address != NULL))
+ /* Copy the data. */
+ memcpy (&elf->state.elf64.ehdr_mem,
+ (char *) map_address + offset, sizeof (Elf64_Ehdr));
+ else
+ /* Read the data. */
+ if (TEMP_FAILURE_RETRY (pread (elf->fildes,
+ &elf->state.elf64.ehdr_mem,
+ sizeof (Elf64_Ehdr), offset))
+ != sizeof (Elf64_Ehdr))
{
/* We must be able to read the ELF header. */
__libelf_seterrno (ELF_E_INVALID_FILE);
@@ -692,8 +740,9 @@ __libelf_next_arhdr (elf)
{
ar_hdr = &elf->state.ar.ar_hdr;
- if (pread (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
- elf->state.ar.offset)
+ if (TEMP_FAILURE_RETRY (pread (elf->fildes, ar_hdr,
+ sizeof (struct ar_hdr),
+ elf->state.ar.offset))
!= sizeof (struct ar_hdr))
{
/* Something went wrong while reading the file. */
diff --git a/elfutils/libelf/elf_error.c b/elfutils/libelf/elf_error.c
index 168ce113..b51962b9 100644
--- a/elfutils/libelf/elf_error.c
+++ b/elfutils/libelf/elf_error.c
@@ -243,6 +243,11 @@ static const char msgstr[] =
(ELF_E_INVALID_PHDR_IDX \
+ sizeof "program header only allowed in executables and shared objects")
N_("file has no program header")
+ "\0"
+#define ELF_E_INVALID_OFFSET_IDX \
+ (ELF_E_NO_PHDR_IDX \
+ + sizeof "file has no program header")
+ N_("invalid offset")
};
@@ -289,7 +294,8 @@ static const uint_fast16_t msgidx[ELF_E_NUM] =
[ELF_E_NOFILE] = ELF_E_NOFILE_IDX,
[ELF_E_GROUP_NOT_REL] = ELF_E_GROUP_NOT_REL_IDX,
[ELF_E_INVALID_PHDR] = ELF_E_INVALID_PHDR_IDX,
- [ELF_E_NO_PHDR] = ELF_E_NO_PHDR_IDX
+ [ELF_E_NO_PHDR] = ELF_E_NO_PHDR_IDX,
+ [ELF_E_INVALID_OFFSET] = ELF_E_INVALID_OFFSET_IDX
};
#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0])))
diff --git a/elfutils/libelf/elf_getaroff.c b/elfutils/libelf/elf_getaroff.c
new file mode 100644
index 00000000..67e2d773
--- /dev/null
+++ b/elfutils/libelf/elf_getaroff.c
@@ -0,0 +1,42 @@
+/* Return offset in archive for current file ELF.
+ Copyright (C) 2005 Red Hat, Inc.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getaroff (elf)
+ Elf *elf;
+{
+ /* Be gratious, the specs demand it. */
+ if (elf == NULL || elf->parent == NULL)
+ return ELF_C_NULL;
+
+ /* We can be sure the parent is an archive. */
+ Elf *parent = elf->parent;
+ assert (parent->kind == ELF_K_AR);
+
+ return parent->state.ar.offset;
+}
diff --git a/elfutils/libelf/elf_getarsym.c b/elfutils/libelf/elf_getarsym.c
index 1dafa9ac..67b2697c 100644
--- a/elfutils/libelf/elf_getarsym.c
+++ b/elfutils/libelf/elf_getarsym.c
@@ -22,6 +22,7 @@
#include <assert.h>
#include <byteswap.h>
#include <endian.h>
+#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -31,6 +32,10 @@
#include "libelfP.h"
+#define pread_retry(fd, buf, len, off) \
+ TEMP_FAILURE_RETRY (pread (fd, buf, len, off))
+
+
Elf_Arsym *
elf_getarsym (elf, ptr)
Elf *elf;
@@ -69,8 +74,8 @@ elf_getarsym (elf, ptr)
{
/* We must read index from the file. */
assert (elf->fildes != -1);
- if (pread (elf->fildes, &elf->state.ar.ar_hdr,
- sizeof (struct ar_hdr), elf->start_offset + SARMAG)
+ if (pread_retry (elf->fildes, &elf->state.ar.ar_hdr,
+ sizeof (struct ar_hdr), elf->start_offset + SARMAG)
!= sizeof (struct ar_hdr))
{
/* It is not possible to read the index. Maybe it does not
@@ -120,8 +125,8 @@ elf_getarsym (elf, ptr)
uint32_t n;
if (elf->map_address == NULL)
{
- if (pread (elf->fildes, &n, sizeof (n),
- elf->start_offset + SARMAG + sizeof (struct ar_hdr))
+ if (pread_retry (elf->fildes, &n, sizeof (n),
+ elf->start_offset + SARMAG + sizeof (struct ar_hdr))
!= sizeof (n))
{
/* Cannot read the number of entries. */
@@ -179,15 +184,17 @@ elf_getarsym (elf, ptr)
char *new_str = (char *) (elf->state.ar.ar_sym + n + 1);
/* Now read the data from the file. */
- if ((size_t) pread (elf->fildes, file_data,
- n * sizeof (uint32_t), elf->start_offset
- + SARMAG + sizeof (struct ar_hdr)
- + sizeof (uint32_t)) != n * sizeof (uint32_t)
- || ((size_t) pread (elf->fildes, new_str,
- index_size - n * sizeof (uint32_t),
- elf->start_offset
- + SARMAG + sizeof (struct ar_hdr)
- + (n + 1) * sizeof (uint32_t))
+ if ((size_t) pread_retry (elf->fildes, file_data,
+ n * sizeof (uint32_t),
+ elf->start_offset + SARMAG
+ + sizeof (struct ar_hdr)
+ + sizeof (uint32_t))
+ != n * sizeof (uint32_t)
+ || ((size_t) pread_retry (elf->fildes, new_str,
+ index_size - n * sizeof (uint32_t),
+ elf->start_offset
+ + SARMAG + sizeof (struct ar_hdr)
+ + (n + 1) * sizeof (uint32_t))
!= index_size - n * sizeof (uint32_t)))
{
/* We were not able to read the data. */
diff --git a/elfutils/libelf/elf_getdata.c b/elfutils/libelf/elf_getdata.c
index 3150649c..20e8e624 100644
--- a/elfutils/libelf/elf_getdata.c
+++ b/elfutils/libelf/elf_getdata.c
@@ -432,8 +432,7 @@ elf_getdata (scn, data)
== offsetof (struct Elf, state.elf64.ehdr))
? elf->state.elf32.ehdr->e_ident[EI_DATA]
: elf->state.elf64.ehdr->e_ident[EI_DATA]),
- scn->rawdata.d.d_size,
- scn->rawdata.d.d_type);
+ scn->rawdata.d.d_size, scn->rawdata.d.d_type);
else
/* This is an empty or NOBITS section. There is no buffer but
the size information etc is important. */
diff --git a/elfutils/libelf/elf_update.c b/elfutils/libelf/elf_update.c
index f7c638d3..5d6c6b7a 100644
--- a/elfutils/libelf/elf_update.c
+++ b/elfutils/libelf/elf_update.c
@@ -120,7 +120,7 @@ elf_update (elf, cmd)
return -1;
}
- rwlock_rdlock (elf->lock);
+ rwlock_wrlock (elf->lock);
/* Make sure we have an ELF header. */
if (elf->state.elf.ehdr == NULL)
diff --git a/elfutils/libelf/gelf.h b/elfutils/libelf/gelf.h
index 299d6c83..369a3a71 100644
--- a/elfutils/libelf/gelf.h
+++ b/elfutils/libelf/gelf.h
@@ -153,6 +153,9 @@ extern int gelf_update_ehdr (Elf *__elf, GElf_Ehdr *__src);
/* Create new ELF header if none exists. */
extern unsigned long int gelf_newehdr (Elf *__elf, int __class);
+/* Get section at OFFSET. */
+extern Elf_Scn *gelf_offscn (Elf *__elf, GElf_Off __offset);
+
/* Retrieve section header. */
extern GElf_Shdr *gelf_getshdr (Elf_Scn *__scn, GElf_Shdr *__dst);
diff --git a/elfutils/libelf/gelf_offscn.c b/elfutils/libelf/gelf_offscn.c
new file mode 100644
index 00000000..c04f990f
--- /dev/null
+++ b/elfutils/libelf/gelf_offscn.c
@@ -0,0 +1,45 @@
+/* Create new ELF header.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+gelf_offscn (elf, offset)
+ Elf *elf;
+ GElf_Off offset;
+{
+ if (elf->class == ELFCLASS32)
+ {
+ if ((Elf32_Off) offset != offset)
+ {
+ __libelf_seterrno (ELF_E_INVALID_OFFSET);
+ return NULL;
+ }
+
+ return INTUSE(elf32_offscn) (elf, (Elf32_Off) offset);
+ }
+
+ return INTUSE(elf64_offscn) (elf, offset);
+}
diff --git a/elfutils/libelf/libelf.h b/elfutils/libelf/libelf.h
index 5b3dc00b..96787dbe 100644
--- a/elfutils/libelf/libelf.h
+++ b/elfutils/libelf/libelf.h
@@ -1,5 +1,5 @@
/* Interface for libelf.
- Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+ Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005 Red Hat, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -199,6 +199,11 @@ extern Elf64_Phdr *elf64_newphdr (Elf *__elf, size_t __cnt);
/* Get section at INDEX. */
extern Elf_Scn *elf_getscn (Elf *__elf, size_t __index);
+/* Get section at OFFSET. */
+extern Elf_Scn *elf32_offscn (Elf *__elf, Elf32_Off __offset);
+/* Similar bug this time the binary calls is ELFCLASS64. */
+extern Elf_Scn *elf64_offscn (Elf *__elf, Elf64_Off __offset);
+
/* Get index of section. */
extern size_t elf_ndxscn (Elf_Scn *__scn);
@@ -266,6 +271,9 @@ extern char *elf_strptr (Elf *__elf, size_t __index, size_t __offset);
/* Return header of archive. */
extern Elf_Arhdr *elf_getarhdr (Elf *__elf);
+/* Return offset in archive for current file ELF. */
+extern off_t elf_getaroff (Elf *__elf);
+
/* Select archive element at OFFSET. */
extern size_t elf_rand (Elf *__elf, size_t __offset);
diff --git a/elfutils/libelf/libelf.map b/elfutils/libelf/libelf.map
index f416da7f..b2a65e84 100644
--- a/elfutils/libelf/libelf.map
+++ b/elfutils/libelf/libelf.map
@@ -104,3 +104,11 @@ ELFUTILS_1.1 {
gelf_getlib;
gelf_update_lib;
} ELFUTILS_1.0;
+
+ELFUTILS_1.1.1 {
+ global:
+ elf32_offscn;
+ elf64_offscn;
+ gelf_offscn;
+ elf_getaroff;
+} ELFUTILS_1.1;
diff --git a/elfutils/libelf/libelfP.h b/elfutils/libelf/libelfP.h
index 100f349a..fd6f825c 100644
--- a/elfutils/libelf/libelfP.h
+++ b/elfutils/libelf/libelfP.h
@@ -117,6 +117,7 @@ enum
ELF_E_GROUP_NOT_REL,
ELF_E_INVALID_PHDR,
ELF_E_NO_PHDR,
+ ELF_E_INVALID_OFFSET,
/* Keep this as the last entry. */
ELF_E_NUM
};
@@ -453,6 +454,10 @@ extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt)
attribute_hidden;
extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt)
attribute_hidden;
+extern Elf_Scn *__elf32_offscn_internal (Elf *__elf, Elf32_Off __offset)
+ attribute_hidden;
+extern Elf_Scn *__elf64_offscn_internal (Elf *__elf, Elf64_Off __offset)
+ attribute_hidden;
extern int __elf_getshnum_internal (Elf *__elf, size_t *__dst)
attribute_hidden;
extern int __elf_getshstrndx_internal (Elf *__elf, size_t *__dst)
diff --git a/elfutils/m4/Makefile.in b/elfutils/m4/Makefile.in
index 836a1a7b..e8485283 100644
--- a/elfutils/m4/Makefile.in
+++ b/elfutils/m4/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -56,6 +56,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -69,6 +71,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -77,12 +81,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
diff --git a/elfutils/po/ChangeLog b/elfutils/po/ChangeLog
index fc65e99a..cea77df8 100644
--- a/elfutils/po/ChangeLog
+++ b/elfutils/po/ChangeLog
@@ -1,3 +1,16 @@
+2005-08-15 Ulrich Drepper <drepper@redhat.com>
+
+ * POTFILES.in: Add src/ranlib.
+
+2005-08-05 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.in.in (XGETTEXT_OPTIONS): Move adding of --flag options
+ after magic Makevars line. Also look for ERROR from elflint.
+
+2005-07-21 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.in.in: Add src/elfcmp.
+
2005-05-07 Ulrich Drepper <drepper@redhat.com>
* Makefile.in.in (XGETTEXT_OPTIONS): Define.
diff --git a/elfutils/po/Makefile.in.in b/elfutils/po/Makefile.in.in
index dbd78851..0110ffbd 100644
--- a/elfutils/po/Makefile.in.in
+++ b/elfutils/po/Makefile.in.in
@@ -33,7 +33,6 @@ mkinstalldirs = $(SHELL) `case "$(MKINSTALLDIRS)" in /*) echo "$(MKINSTALLDIRS)"
GMSGFMT = @GMSGFMT@
MSGFMT = @MSGFMT@
XGETTEXT = @XGETTEXT@
-XGETTEXT_OPTIONS = --flag=error:3:c-format
MSGMERGE = msgmerge
MSGMERGE_UPDATE = @MSGMERGE@ --update
MSGINIT = msginit
@@ -56,6 +55,8 @@ CATALOGS = @CATALOGS@
# Makevars gets inserted here. (Don't remove this line!)
+XGETTEXT_OPTIONS += --flag=error:3:c-format --flag=ERROR:1:c-format
+
.SUFFIXES:
.SUFFIXES: .po .gmo .mo .nop .po-update
diff --git a/elfutils/po/POTFILES.in b/elfutils/po/POTFILES.in
index dffb85e3..c45ee76d 100644
--- a/elfutils/po/POTFILES.in
+++ b/elfutils/po/POTFILES.in
@@ -21,3 +21,5 @@ src/ldscript.y
src/elflint.c
src/addr2line.c
src/findtextrel.c
+src/elfcmp.c
+src/ranlib.c
diff --git a/elfutils/po/elfutils.pot b/elfutils/po/elfutils.pot
index c8b01fca..e4a11db9 100644
--- a/elfutils/po/elfutils.pot
+++ b/elfutils/po/elfutils.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2005-05-09 22:10-0700\n"
+"POT-Creation-Date: 2005-08-24 14:41-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,18 +18,20 @@ msgstr ""
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: lib/xmalloc.c:38 lib/xmalloc.c:52 lib/xmalloc.c:66
+#, c-format
msgid "memory exhausted"
msgstr ""
-#: libasm/asm_error.c:108 libdw/dwarf_error.c:74
+#: libasm/asm_error.c:108 libdw/dwarf_error.c:75
msgid "no error"
msgstr ""
-#: libasm/asm_error.c:109 libdw/dwarf_error.c:83
+#: libasm/asm_error.c:109 libdw/dwarf_error.c:84
msgid "out of memory"
msgstr ""
#: libasm/asm_error.c:110 src/ldgeneric.c:2474
+#, c-format
msgid "cannot create output file"
msgstr ""
@@ -42,6 +44,7 @@ msgid "cannot change mode of output file"
msgstr ""
#: libasm/asm_error.c:113 src/ldgeneric.c:6246
+#, c-format
msgid "cannot rename output file"
msgstr ""
@@ -53,138 +56,146 @@ msgstr ""
msgid "invalid section type for operation"
msgstr ""
-#: libasm/asm_error.c:149
+#: libasm/asm_error.c:116
+msgid "error during output of data"
+msgstr ""
+
+#: libasm/asm_error.c:150
msgid "Unknown error"
msgstr ""
-#: libdw/dwarf_error.c:75
+#: libdw/dwarf_error.c:76
msgid "unknown error"
msgstr ""
-#: libdw/dwarf_error.c:76
+#: libdw/dwarf_error.c:77
msgid "invalid access"
msgstr ""
-#: libdw/dwarf_error.c:77
+#: libdw/dwarf_error.c:78
msgid "no regular file"
msgstr ""
-#: libdw/dwarf_error.c:78
+#: libdw/dwarf_error.c:79
msgid "I/O error"
msgstr ""
-#: libdw/dwarf_error.c:79
+#: libdw/dwarf_error.c:80
msgid "invalid ELF file"
msgstr ""
-#: libdw/dwarf_error.c:80
+#: libdw/dwarf_error.c:81
msgid "no DWARF information"
msgstr ""
-#: libdw/dwarf_error.c:81
+#: libdw/dwarf_error.c:82
msgid "no ELF file"
msgstr ""
-#: libdw/dwarf_error.c:82
+#: libdw/dwarf_error.c:83
msgid "cannot get ELF header"
msgstr ""
-#: libdw/dwarf_error.c:84
+#: libdw/dwarf_error.c:85
msgid "not implemented"
msgstr ""
-#: libdw/dwarf_error.c:85
+#: libdw/dwarf_error.c:86
msgid "invalid command"
msgstr ""
-#: libdw/dwarf_error.c:86
+#: libdw/dwarf_error.c:87
msgid "invalid version"
msgstr ""
-#: libdw/dwarf_error.c:87
+#: libdw/dwarf_error.c:88
msgid "invalid file"
msgstr ""
-#: libdw/dwarf_error.c:88
+#: libdw/dwarf_error.c:89
msgid "no entries found"
msgstr ""
-#: libdw/dwarf_error.c:89
+#: libdw/dwarf_error.c:90
msgid "invalid DWARF"
msgstr ""
-#: libdw/dwarf_error.c:90
+#: libdw/dwarf_error.c:91
msgid "no string data"
msgstr ""
-#: libdw/dwarf_error.c:91
+#: libdw/dwarf_error.c:92
msgid "no address value"
msgstr ""
-#: libdw/dwarf_error.c:92
+#: libdw/dwarf_error.c:93
msgid "no constant value"
msgstr ""
-#: libdw/dwarf_error.c:93
+#: libdw/dwarf_error.c:94
msgid "no reference value"
msgstr ""
-#: libdw/dwarf_error.c:94
+#: libdw/dwarf_error.c:95
msgid "invalid reference value"
msgstr ""
-#: libdw/dwarf_error.c:95
+#: libdw/dwarf_error.c:96
msgid ".debug_line section missing"
msgstr ""
-#: libdw/dwarf_error.c:96
+#: libdw/dwarf_error.c:97
msgid "invalid .debug_line section"
msgstr ""
-#: libdw/dwarf_error.c:97
+#: libdw/dwarf_error.c:98
msgid "debug information too big"
msgstr ""
-#: libdw/dwarf_error.c:98
+#: libdw/dwarf_error.c:99
msgid "invalid DWARF version"
msgstr ""
-#: libdw/dwarf_error.c:99
+#: libdw/dwarf_error.c:100
msgid "invalid directory index"
msgstr ""
-#: libdw/dwarf_error.c:100
+#: libdw/dwarf_error.c:101
msgid "address out of range"
msgstr ""
-#: libdw/dwarf_error.c:101
+#: libdw/dwarf_error.c:102
msgid "no location list value"
msgstr ""
-#: libdw/dwarf_error.c:102
+#: libdw/dwarf_error.c:103
msgid "no block data"
msgstr ""
-#: libdw/dwarf_error.c:103
+#: libdw/dwarf_error.c:104
msgid "invalid line index"
msgstr ""
-#: libdw/dwarf_error.c:104
+#: libdw/dwarf_error.c:105
msgid "invalid address range index"
msgstr ""
-#: libdw/dwarf_error.c:105
+#: libdw/dwarf_error.c:106
msgid "no matching address range"
msgstr ""
-#: libdw/dwarf_error.c:106
+#: libdw/dwarf_error.c:107
msgid "no flag value"
msgstr ""
-#: libdw/dwarf_error.c:107
+#: libdw/dwarf_error.c:108
msgid "invalid offset"
msgstr ""
+#: libdw/dwarf_error.c:109
+msgid ".debug_ranges section missing"
+msgstr ""
+
#: src/nm.c:62 src/readelf.c:54 src/strip.c:60
msgid "Output selection:"
msgstr ""
@@ -263,7 +274,7 @@ msgstr ""
msgid "Reverse the sense of the sort"
msgstr ""
-#: src/nm.c:91 src/addr2line.c:59 src/findtextrel.c:61
+#: src/nm.c:91 src/addr2line.c:56 src/findtextrel.c:61 src/elfcmp.c:59
msgid "Miscellaneous:"
msgstr ""
@@ -271,17 +282,18 @@ msgstr ""
msgid "List symbols from FILEs (a.out by default)."
msgstr ""
-#: src/nm.c:99 src/size.c:80 src/strip.c:80 src/findtextrel.c:70
+#: src/nm.c:99 src/size.c:80 src/strip.c:84 src/findtextrel.c:70
msgid "[FILE...]"
msgstr ""
-#: src/nm.c:124 src/size.c:105 src/strip.c:104
+#: src/nm.c:124 src/size.c:105 src/strip.c:108
#, c-format
msgid "%s: INTERNAL ERROR %d (%s-%s): %s"
msgstr ""
-#: src/nm.c:241 src/readelf.c:351 src/size.c:207 src/strip.c:187 src/ld.c:857
-#: src/elflint.c:220 src/addr2line.c:216 src/findtextrel.c:156
+#: src/nm.c:241 src/readelf.c:356 src/size.c:207 src/strip.c:191 src/ld.c:857
+#: src/elflint.c:220 src/addr2line.c:168 src/findtextrel.c:156
+#: src/elfcmp.c:493 src/ranlib.c:139
#, c-format
msgid ""
"Copyright (C) %s Red Hat, Inc.\n"
@@ -289,14 +301,15 @@ msgid ""
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
msgstr ""
-#: src/nm.c:246 src/readelf.c:356 src/size.c:212 src/strip.c:192 src/ld.c:862
-#: src/elflint.c:225 src/addr2line.c:221 src/findtextrel.c:161
+#: src/nm.c:246 src/readelf.c:361 src/size.c:212 src/strip.c:196 src/ld.c:862
+#: src/elflint.c:225 src/addr2line.c:173 src/findtextrel.c:161
+#: src/elfcmp.c:498 src/ranlib.c:144
#, c-format
msgid "Written by %s.\n"
msgstr ""
-#: src/nm.c:351 src/strip.c:402 src/strip.c:437 src/addr2line.c:128
-#: src/findtextrel.c:215
+#: src/nm.c:351 src/strip.c:418 src/strip.c:453 src/findtextrel.c:215
+#: src/ranlib.c:293
#, c-format
msgid "cannot open '%s'"
msgstr ""
@@ -306,7 +319,7 @@ msgstr ""
msgid "while close '%s'"
msgstr ""
-#: src/nm.c:390 src/strip.c:326
+#: src/nm.c:390 src/strip.c:346
#, c-format
msgid "%s: File format not recognized"
msgstr ""
@@ -328,6 +341,7 @@ msgid "%s in %s\n"
msgstr ""
#: src/nm.c:452
+#, c-format
msgid "cannot reset archive offset to beginning"
msgstr ""
@@ -336,19 +350,21 @@ msgstr ""
msgid "%s%s%s: file format not recognized"
msgstr ""
-#: src/nm.c:695
+#: src/nm.c:688
+#, c-format
msgid "cannot create search tree"
msgstr ""
-#: src/nm.c:723 src/nm.c:968 src/readelf.c:666 src/readelf.c:809
-#: src/readelf.c:962 src/readelf.c:1146 src/readelf.c:1365 src/readelf.c:1524
-#: src/readelf.c:1697 src/readelf.c:1956 src/readelf.c:2033 src/readelf.c:2121
-#: src/readelf.c:2402 src/readelf.c:2528 src/readelf.c:4636 src/size.c:414
-#: src/size.c:489 src/strip.c:451
+#: src/nm.c:716 src/nm.c:961 src/readelf.c:671 src/readelf.c:814
+#: src/readelf.c:967 src/readelf.c:1151 src/readelf.c:1370 src/readelf.c:1529
+#: src/readelf.c:1702 src/readelf.c:1957 src/readelf.c:2023 src/readelf.c:2102
+#: src/readelf.c:2384 src/readelf.c:2510 src/readelf.c:4823 src/size.c:414
+#: src/size.c:489 src/strip.c:468
+#, c-format
msgid "cannot get section header string table index"
msgstr ""
-#: src/nm.c:743
+#: src/nm.c:736
#, c-format
msgid ""
"\n"
@@ -357,7 +373,7 @@ msgid ""
"\n"
msgstr ""
-#: src/nm.c:745
+#: src/nm.c:738
#, c-format
msgid ""
"\n"
@@ -366,29 +382,29 @@ msgid ""
"\n"
msgstr ""
-#: src/nm.c:748
+#: src/nm.c:741
#, c-format
msgid ""
"%*s%-*s %-*s Class Type %-*s %*s Section\n"
"\n"
msgstr ""
-#: src/nm.c:978
+#: src/nm.c:971
#, c-format
msgid "%s: entry size in section `%s' is not what we expect"
msgstr ""
-#: src/nm.c:982
+#: src/nm.c:975
#, c-format
msgid "%s: size of section `%s' is not multiple of entry size"
msgstr ""
-#: src/nm.c:1215
+#: src/nm.c:1208
#, c-format
msgid "%s%s%s%s: Invalid operation"
msgstr ""
-#: src/nm.c:1272
+#: src/nm.c:1265
#, c-format
msgid "%s%s%s: no symbols"
msgstr ""
@@ -432,315 +448,320 @@ msgstr ""
#: src/readelf.c:66
msgid ""
"Display DWARF section content. SECTION can be one of abbrev, aranges, "
-"frame, info, loc, line, pubnames, str, or macinfo."
+"frame, info, loc, line, ranges, pubnames, str, or macinfo."
msgstr ""
-#: src/readelf.c:68
+#: src/readelf.c:69
msgid "Display the core notes"
msgstr ""
-#: src/readelf.c:70
+#: src/readelf.c:71
msgid "Display architecture specific information (if any)"
msgstr ""
-#: src/readelf.c:72
+#: src/readelf.c:73
msgid "Output control:"
msgstr ""
-#: src/readelf.c:78
+#: src/readelf.c:79
msgid "Print information from ELF file in human-readable form."
msgstr ""
-#: src/readelf.c:82 src/elflint.c:69
+#: src/readelf.c:83 src/elflint.c:69
msgid "FILE..."
msgstr ""
-#: src/readelf.c:200 src/elflint.c:139
+#: src/readelf.c:203 src/elflint.c:139
+#, c-format
msgid "cannot open input file"
msgstr ""
-#: src/readelf.c:207 src/elflint.c:146
+#: src/readelf.c:210 src/elflint.c:146
#, c-format
msgid "cannot generate Elf descriptor: %s\n"
msgstr ""
-#: src/readelf.c:215
+#: src/readelf.c:218
#, c-format
msgid "error while closing Elf descriptor: %s"
msgstr ""
-#: src/readelf.c:318
+#: src/readelf.c:323
#, c-format
msgid "Unknown DWARF debug section `%s'.\n"
msgstr ""
-#: src/readelf.c:327 src/elflint.c:203
+#: src/readelf.c:332 src/elflint.c:203
msgid "Missing file name.\n"
msgstr ""
-#: src/readelf.c:332
+#: src/readelf.c:337
msgid "No operation specified.\n"
msgstr ""
-#: src/readelf.c:411 src/elflint.c:283
+#: src/readelf.c:416 src/elflint.c:283 src/ranlib.c:369
#, c-format
msgid " error while freeing sub-ELF descriptor: %s\n"
msgstr ""
-#: src/readelf.c:419
+#: src/readelf.c:424
+#, c-format
msgid "cannot stat input file"
msgstr ""
-#: src/readelf.c:421
+#: src/readelf.c:426
+#, c-format
msgid "input file is empty"
msgstr ""
-#: src/readelf.c:424 src/elflint.c:291
+#: src/readelf.c:429
+#, c-format
msgid "Not an ELF file - it has the wrong magic bytes at the start"
msgstr ""
-#: src/readelf.c:451
+#: src/readelf.c:456
#, c-format
msgid "cannot read ELF header: %s"
msgstr ""
-#: src/readelf.c:458
+#: src/readelf.c:463
+#, c-format
msgid "cannot create EBL handle"
msgstr ""
-#: src/readelf.c:465 src/strip.c:513 src/ldgeneric.c:592 src/ldgeneric.c:1026
+#: src/readelf.c:470 src/strip.c:528 src/ldgeneric.c:592 src/ldgeneric.c:1026
#, c-format
msgid "cannot determine number of sections: %s"
msgstr ""
-#: src/readelf.c:507
+#: src/readelf.c:512
msgid "NONE (None)"
msgstr ""
-#: src/readelf.c:508
+#: src/readelf.c:513
msgid "REL (Relocatable file)"
msgstr ""
-#: src/readelf.c:509
+#: src/readelf.c:514
msgid "EXEC (Executable file)"
msgstr ""
-#: src/readelf.c:510
+#: src/readelf.c:515
msgid "DYN (Shared object file)"
msgstr ""
-#: src/readelf.c:511
+#: src/readelf.c:516
msgid "CORE (Core file)"
msgstr ""
-#: src/readelf.c:516
+#: src/readelf.c:521
#, c-format
msgid "OS Specific: (%x)\n"
msgstr ""
-#: src/readelf.c:518
+#: src/readelf.c:523
#, c-format
msgid "Processor Specific: (%x)\n"
msgstr ""
-#: src/readelf.c:531
+#: src/readelf.c:536
msgid ""
"ELF Header:\n"
" Magic: "
msgstr ""
-#: src/readelf.c:535
+#: src/readelf.c:540
#, c-format
msgid ""
"\n"
" Class: %s\n"
msgstr ""
-#: src/readelf.c:540
+#: src/readelf.c:545
#, c-format
msgid " Data: %s\n"
msgstr ""
-#: src/readelf.c:546
+#: src/readelf.c:551
#, c-format
msgid " Version: %hhd %s\n"
msgstr ""
-#: src/readelf.c:548 src/readelf.c:564
+#: src/readelf.c:553 src/readelf.c:569
msgid "(current)"
msgstr ""
-#: src/readelf.c:551
+#: src/readelf.c:556
#, c-format
msgid " OS/ABI: %s\n"
msgstr ""
-#: src/readelf.c:554
+#: src/readelf.c:559
#, c-format
msgid " ABI Version: %hhd\n"
msgstr ""
-#: src/readelf.c:557
+#: src/readelf.c:562
msgid " Type: "
msgstr ""
-#: src/readelf.c:560
+#: src/readelf.c:565
#, c-format
msgid " Machine: %s\n"
msgstr ""
-#: src/readelf.c:562
+#: src/readelf.c:567
#, c-format
msgid " Version: %d %s\n"
msgstr ""
-#: src/readelf.c:566
+#: src/readelf.c:571
#, c-format
msgid " Entry point address: %#<PRIx64>\n"
msgstr ""
-#: src/readelf.c:569
+#: src/readelf.c:574
#, c-format
msgid " Start of program headers: %<PRId64> %s\n"
msgstr ""
-#: src/readelf.c:570 src/readelf.c:573
+#: src/readelf.c:575 src/readelf.c:578
msgid "(bytes into file)"
msgstr ""
-#: src/readelf.c:572
+#: src/readelf.c:577
#, c-format
msgid " Start of section headers: %<PRId64> %s\n"
msgstr ""
-#: src/readelf.c:575
+#: src/readelf.c:580
#, c-format
msgid " Flags: %s\n"
msgstr ""
-#: src/readelf.c:578
+#: src/readelf.c:583
#, c-format
msgid " Size of this header: %<PRId16> %s\n"
msgstr ""
-#: src/readelf.c:579 src/readelf.c:582 src/readelf.c:588
+#: src/readelf.c:584 src/readelf.c:587 src/readelf.c:593
msgid "(bytes)"
msgstr ""
-#: src/readelf.c:581
+#: src/readelf.c:586
#, c-format
msgid " Size of program header entries: %<PRId16> %s\n"
msgstr ""
-#: src/readelf.c:584
+#: src/readelf.c:589
#, c-format
msgid " Number of program headers entries: %<PRId16>\n"
msgstr ""
-#: src/readelf.c:587
+#: src/readelf.c:592
#, c-format
msgid " Size of section header entries: %<PRId16> %s\n"
msgstr ""
-#: src/readelf.c:590
+#: src/readelf.c:595
#, c-format
msgid " Number of section headers entries: %<PRId16>"
msgstr ""
-#: src/readelf.c:599
+#: src/readelf.c:604
#, c-format
msgid " (%<PRIu32> in [0].sh_size)"
msgstr ""
-#: src/readelf.c:602 src/readelf.c:618
+#: src/readelf.c:607 src/readelf.c:623
msgid " ([0] not available)"
msgstr ""
-#: src/readelf.c:614
+#: src/readelf.c:619
#, c-format
msgid " (%<PRIu32> in [0].sh_link)"
msgstr ""
-#: src/readelf.c:622
+#: src/readelf.c:627
#, c-format
msgid ""
" Section header string table index: XINDEX%s\n"
"\n"
msgstr ""
-#: src/readelf.c:626
+#: src/readelf.c:631
#, c-format
msgid ""
" Section header string table index: %<PRId16>\n"
"\n"
msgstr ""
-#: src/readelf.c:658
+#: src/readelf.c:663
#, c-format
msgid ""
"There are %d section headers, starting at offset %#<PRIx64>:\n"
"\n"
msgstr ""
-#: src/readelf.c:668
+#: src/readelf.c:673
msgid "Section Headers:"
msgstr ""
-#: src/readelf.c:671
+#: src/readelf.c:676
msgid ""
"[Nr] Name Type Addr Off Size ES Flags Lk "
"Inf Al"
msgstr ""
-#: src/readelf.c:673
+#: src/readelf.c:678
msgid ""
"[Nr] Name Type Addr Off Size ES "
"Flags Lk Inf Al"
msgstr ""
-#: src/readelf.c:685 src/readelf.c:838
+#: src/readelf.c:690 src/readelf.c:843
#, c-format
msgid "cannot get section: %s"
msgstr ""
-#: src/readelf.c:691 src/readelf.c:845
+#: src/readelf.c:696 src/readelf.c:850
#, c-format
msgid "cannot get section header: %s"
msgstr ""
-#: src/readelf.c:750
+#: src/readelf.c:755
msgid "Program Headers:"
msgstr ""
-#: src/readelf.c:752
+#: src/readelf.c:757
msgid ""
" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"
msgstr ""
-#: src/readelf.c:755
+#: src/readelf.c:760
msgid ""
" Type Offset VirtAddr PhysAddr FileSiz "
"MemSiz Flg Align"
msgstr ""
-#: src/readelf.c:795
+#: src/readelf.c:800
#, c-format
msgid "\t[Requesting program interpreter: %s]\n"
msgstr ""
-#: src/readelf.c:811
+#: src/readelf.c:816
msgid ""
"\n"
" Section to Segment mapping:\n"
" Segment Sections..."
msgstr ""
-#: src/readelf.c:824
+#: src/readelf.c:829
#, c-format
msgid "cannot get program header: %s"
msgstr ""
-#: src/readelf.c:967
+#: src/readelf.c:972
#, c-format
msgid ""
"\n"
@@ -751,7 +772,7 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:972
+#: src/readelf.c:977
#, c-format
msgid ""
"\n"
@@ -762,20 +783,20 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:980
+#: src/readelf.c:985
msgid "<INVALID SYMBOL>"
msgstr ""
-#: src/readelf.c:992
+#: src/readelf.c:997
#, c-format
msgid " [%2u] <INVALID SECTION>\n"
msgstr ""
-#: src/readelf.c:997
+#: src/readelf.c:1002
msgid "<INVALID SECTION>"
msgstr ""
-#: src/readelf.c:1148
+#: src/readelf.c:1153
#, c-format
msgid ""
"\n"
@@ -788,43 +809,43 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:1160
+#: src/readelf.c:1165
msgid " Type Value\n"
msgstr ""
-#: src/readelf.c:1186
+#: src/readelf.c:1191
#, c-format
msgid "Shared library: [%s]\n"
msgstr ""
-#: src/readelf.c:1191
+#: src/readelf.c:1196
#, c-format
msgid "Library soname: [%s]\n"
msgstr ""
-#: src/readelf.c:1196
+#: src/readelf.c:1201
#, c-format
msgid "Library rpath: [%s]\n"
msgstr ""
-#: src/readelf.c:1201
+#: src/readelf.c:1206
#, c-format
msgid "Library runpath: [%s]\n"
msgstr ""
-#: src/readelf.c:1221
+#: src/readelf.c:1226
#, c-format
msgid "%<PRId64> (bytes)\n"
msgstr ""
-#: src/readelf.c:1340 src/readelf.c:1497
+#: src/readelf.c:1345 src/readelf.c:1502
#, c-format
msgid ""
"\n"
"Invalid symbol table at offset %#0<PRIx64>\n"
msgstr ""
-#: src/readelf.c:1368
+#: src/readelf.c:1373
#, c-format
msgid ""
"\n"
@@ -837,7 +858,7 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:1383
+#: src/readelf.c:1388
#, c-format
msgid ""
"\n"
@@ -848,28 +869,28 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:1393
+#: src/readelf.c:1398
msgid " Offset Type Value Name\n"
msgstr ""
-#: src/readelf.c:1395
+#: src/readelf.c:1400
msgid " Offset Type Value Name\n"
msgstr ""
-#: src/readelf.c:1422 src/readelf.c:1433 src/readelf.c:1451 src/readelf.c:1463
-#: src/readelf.c:1566 src/readelf.c:1578 src/readelf.c:1597 src/readelf.c:1610
+#: src/readelf.c:1427 src/readelf.c:1438 src/readelf.c:1456 src/readelf.c:1468
+#: src/readelf.c:1571 src/readelf.c:1583 src/readelf.c:1602 src/readelf.c:1615
msgid "<INVALID RELOC>"
msgstr ""
-#: src/readelf.c:1423 src/readelf.c:1567
+#: src/readelf.c:1428 src/readelf.c:1572
msgid "INVALID SYMBOL"
msgstr ""
-#: src/readelf.c:1452 src/readelf.c:1598
+#: src/readelf.c:1457 src/readelf.c:1603
msgid "INVALID SECTION"
msgstr ""
-#: src/readelf.c:1526
+#: src/readelf.c:1531
#, c-format
msgid ""
"\n"
@@ -882,15 +903,15 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:1538
+#: src/readelf.c:1543
msgid " Offset Type Value Addend Name\n"
msgstr ""
-#: src/readelf.c:1540
+#: src/readelf.c:1545
msgid " Offset Type Value Addend Name\n"
msgstr ""
-#: src/readelf.c:1703
+#: src/readelf.c:1708
#, c-format
msgid ""
"\n"
@@ -901,39 +922,40 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:1708
+#: src/readelf.c:1713
#, c-format
msgid " %lu local symbol String table: [%2u] '%s'\n"
msgid_plural " %lu local symbols String table: [%2u] '%s'\n"
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:1718
+#: src/readelf.c:1723
msgid " Num: Value Size Type Bind Vis Ndx Name\n"
msgstr ""
-#: src/readelf.c:1720
+#: src/readelf.c:1725
msgid " Num: Value Size Type Bind Vis Ndx Name\n"
msgstr ""
-#: src/readelf.c:1740
+#: src/readelf.c:1745
#, c-format
msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
msgstr ""
-#: src/readelf.c:1830
+#: src/readelf.c:1835
+#, c-format
msgid "bad dynamic symbol"
msgstr ""
-#: src/readelf.c:1913
+#: src/readelf.c:1918
msgid "none"
msgstr ""
-#: src/readelf.c:1930
+#: src/readelf.c:1935
msgid "| <unknown>"
msgstr ""
-#: src/readelf.c:1958
+#: src/readelf.c:1960
#, c-format
msgid ""
"\n"
@@ -946,17 +968,17 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:1985
+#: src/readelf.c:1983
#, c-format
msgid " %#06x: Version: %hu File: %s Cnt: %hu\n"
msgstr ""
-#: src/readelf.c:2000
+#: src/readelf.c:1996
#, c-format
msgid " %#06x: Name: %s Flags: %s Version: %hu\n"
msgstr ""
-#: src/readelf.c:2035
+#: src/readelf.c:2027
#, c-format
msgid ""
"\n"
@@ -969,17 +991,17 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:2070
+#: src/readelf.c:2057
#, c-format
msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"
msgstr ""
-#: src/readelf.c:2085
+#: src/readelf.c:2072
#, c-format
msgid " %#06x: Parent %d: %s\n"
msgstr ""
-#: src/readelf.c:2334
+#: src/readelf.c:2316
#, c-format
msgid ""
"\n"
@@ -992,20 +1014,20 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:2366
+#: src/readelf.c:2348
msgid " 0 *local* "
msgstr ""
-#: src/readelf.c:2371
+#: src/readelf.c:2353
msgid " 1 *global* "
msgstr ""
-#: src/readelf.c:2427
+#: src/readelf.c:2409
#, c-format
msgid "cannot get data for section %d: %s"
msgstr ""
-#: src/readelf.c:2437
+#: src/readelf.c:2419
#, c-format
msgid ""
"\n"
@@ -1020,29 +1042,29 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:2482
+#: src/readelf.c:2464
#, c-format
msgid " Length Number % of total Coverage"
msgstr ""
-#: src/readelf.c:2483
+#: src/readelf.c:2465
#, c-format
msgid " 0 %6<PRIu32> %5.1f%%\n"
msgstr ""
-#: src/readelf.c:2489
+#: src/readelf.c:2471
#, c-format
msgid "%7d %6<PRIu32> %5.1f%% %5.1f%%\n"
msgstr ""
-#: src/readelf.c:2503
+#: src/readelf.c:2485
#, c-format
msgid ""
" Average number of tests: successful lookup: %f\n"
" unsuccessful lookup: %f\n"
msgstr ""
-#: src/readelf.c:2538
+#: src/readelf.c:2520
#, c-format
msgid ""
"\n"
@@ -1053,38 +1075,38 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:2552
+#: src/readelf.c:2534
msgid ""
" Library Time Stamp Checksum Version "
"Flags"
msgstr ""
-#: src/readelf.c:2663
+#: src/readelf.c:2657
#, c-format
msgid "unknown tag %hx"
msgstr ""
-#: src/readelf.c:2665
+#: src/readelf.c:2659
#, c-format
msgid "unknown user tag %hx"
msgstr ""
-#: src/readelf.c:2848
+#: src/readelf.c:2855
#, c-format
msgid "unknown attribute %hx"
msgstr ""
-#: src/readelf.c:2851
+#: src/readelf.c:2858
#, c-format
msgid "unknown user attribute %hx"
msgstr ""
-#: src/readelf.c:2897
+#: src/readelf.c:2904
#, c-format
msgid "unknown form %<PRIx64>"
msgstr ""
-#: src/readelf.c:3446
+#: src/readelf.c:3454
#, c-format
msgid ""
"\n"
@@ -1092,30 +1114,37 @@ msgid ""
" [ Code]\n"
msgstr ""
-#: src/readelf.c:3460
+#: src/readelf.c:3461
#, c-format
-msgid " *** error while reading abbreviation: %s\n"
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
msgstr ""
#: src/readelf.c:3474
#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr ""
+
+#: src/readelf.c:3490
+#, c-format
msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
msgstr ""
-#: src/readelf.c:3477
+#: src/readelf.c:3493
msgid "yes"
msgstr ""
-#: src/readelf.c:3477
+#: src/readelf.c:3493
msgid "no"
msgstr ""
-#: src/readelf.c:3511
+#: src/readelf.c:3529
#, c-format
msgid "cannot get .debug_aranges content: %s"
msgstr ""
-#: src/readelf.c:3516
+#: src/readelf.c:3534
#, c-format
msgid ""
"\n"
@@ -1126,33 +1155,46 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:3546
+#: src/readelf.c:3564
#, c-format
msgid " [%*zu] ???\n"
msgstr ""
-#: src/readelf.c:3548
+#: src/readelf.c:3566
#, c-format
msgid ""
" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
msgstr ""
-#: src/readelf.c:3585
+#: src/readelf.c:3584
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ""
+
+#: src/readelf.c:3589 src/readelf.c:4066 src/readelf.c:4491 src/readelf.c:4581
+#: src/readelf.c:4753
+#, c-format
+msgid ""
+"\n"
+"DWARF section '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:3673
#, c-format
msgid "cannot get attribute code: %s"
msgstr ""
-#: src/readelf.c:3593
+#: src/readelf.c:3681
#, c-format
msgid "cannot get attribute form: %s"
msgstr ""
-#: src/readelf.c:3605
+#: src/readelf.c:3693
#, c-format
msgid "cannot get attribute value: %s"
msgstr ""
-#: src/readelf.c:3741
+#: src/readelf.c:3859
#, c-format
msgid ""
"\n"
@@ -1160,7 +1202,7 @@ msgid ""
" [Offset]\n"
msgstr ""
-#: src/readelf.c:3766
+#: src/readelf.c:3884
#, c-format
msgid ""
" Compilation unit at offset %<PRIu64>:\n"
@@ -1168,49 +1210,49 @@ msgid ""
"<PRIu8>, Offset size: %<PRIu8>\n"
msgstr ""
-#: src/readelf.c:3783
+#: src/readelf.c:3901
#, c-format
msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
msgstr ""
-#: src/readelf.c:3794
+#: src/readelf.c:3912
#, c-format
msgid "cannot get DIE offset: %s"
msgstr ""
-#: src/readelf.c:3802
+#: src/readelf.c:3920
#, c-format
msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
msgstr ""
-#: src/readelf.c:3915
+#: src/readelf.c:4037
#, c-format
msgid "cannot get next DIE: %s\n"
msgstr ""
-#: src/readelf.c:3922
+#: src/readelf.c:4044
#, c-format
msgid "cannot get next DIE: %s"
msgstr ""
-#: src/readelf.c:3944 src/readelf.c:4358 src/readelf.c:4394 src/readelf.c:4566
+#: src/readelf.c:4078
#, c-format
-msgid ""
-"\n"
-"DWARF section '%s' at offset %#<PRIx64>:\n"
+msgid "cannot get line data section data: %s"
msgstr ""
-#: src/readelf.c:3956
+#: src/readelf.c:4091
#, c-format
-msgid "cannot get line data section data: %s"
+msgid ""
+"\n"
+"Table at offset %Zu:\n"
msgstr ""
-#: src/readelf.c:3976
+#: src/readelf.c:4100
#, c-format
msgid "invalid data in section [%zu] '%s'"
msgstr ""
-#: src/readelf.c:4019
+#: src/readelf.c:4143
#, c-format
msgid ""
"\n"
@@ -1226,134 +1268,139 @@ msgid ""
"Opcodes:\n"
msgstr ""
-#: src/readelf.c:4045
+#: src/readelf.c:4169
#, c-format
msgid " [%*<PRIuFAST8>] %hhu argument\n"
msgid_plural " [%*<PRIuFAST8>] %hhu arguments\n"
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:4053
+#: src/readelf.c:4177
msgid ""
"\n"
"Directory table:"
msgstr ""
-#: src/readelf.c:4069
+#: src/readelf.c:4193
msgid ""
"\n"
"File name table:\n"
" Entry Dir Time Size Name"
msgstr ""
-#: src/readelf.c:4098
+#: src/readelf.c:4222
msgid ""
"\n"
"Line number statements:"
msgstr ""
-#: src/readelf.c:4158
+#: src/readelf.c:4282
#, c-format
msgid " special opcode %u: address+%u = %#<PRIx64>, line%+d = %zu\n"
msgstr ""
-#: src/readelf.c:4178
+#: src/readelf.c:4302
#, c-format
msgid " extended opcode %u: "
msgstr ""
-#: src/readelf.c:4183
+#: src/readelf.c:4307
msgid "end of sequence"
msgstr ""
-#: src/readelf.c:4196
+#: src/readelf.c:4320
#, c-format
msgid "set address to %#<PRIx64>\n"
msgstr ""
-#: src/readelf.c:4216
+#: src/readelf.c:4340
#, c-format
msgid "define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
msgstr ""
-#: src/readelf.c:4225
+#: src/readelf.c:4349
msgid "unknown opcode"
msgstr ""
-#: src/readelf.c:4237
+#: src/readelf.c:4361
msgid " copy"
msgstr ""
-#: src/readelf.c:4245
+#: src/readelf.c:4369
#, c-format
msgid " advance address by %u to %#<PRIx64>\n"
msgstr ""
-#: src/readelf.c:4255
+#: src/readelf.c:4379
#, c-format
msgid " advance line by constant %d to %<PRId64>\n"
msgstr ""
-#: src/readelf.c:4263
+#: src/readelf.c:4387
#, c-format
msgid " set file to %<PRIu64>\n"
msgstr ""
-#: src/readelf.c:4273
+#: src/readelf.c:4397
#, c-format
msgid " set column to %<PRIu64>\n"
msgstr ""
-#: src/readelf.c:4280
+#: src/readelf.c:4404
#, c-format
msgid " set '%s' to %<PRIuFAST8>\n"
msgstr ""
-#: src/readelf.c:4286
+#: src/readelf.c:4410
msgid " set basic block flag"
msgstr ""
-#: src/readelf.c:4294
+#: src/readelf.c:4418
#, c-format
msgid " advance address by constant %u to %#<PRIx64>\n"
msgstr ""
-#: src/readelf.c:4307
+#: src/readelf.c:4431
#, c-format
msgid " advance address by fixed value %u to %#<PRIx64>\n"
msgstr ""
-#: src/readelf.c:4314
+#: src/readelf.c:4438
msgid " set prologue end flag"
msgstr ""
-#: src/readelf.c:4319
+#: src/readelf.c:4443
msgid " set epilogue begin flag"
msgstr ""
-#: src/readelf.c:4328
+#: src/readelf.c:4452
#, c-format
msgid " unknown opcode with %<PRIu8> parameter:"
msgid_plural " unknown opcode with %<PRIu8> parameters:"
msgstr[0] ""
msgstr[1] ""
-#: src/readelf.c:4404
+#: src/readelf.c:4486
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ""
+
+#: src/readelf.c:4591
#, c-format
msgid "cannot get macro information section data: %s"
msgstr ""
-#: src/readelf.c:4483
+#: src/readelf.c:4670
#, c-format
msgid "%*s*** non-terminated string at end of section"
msgstr ""
-#: src/readelf.c:4551
+#: src/readelf.c:4738
#, c-format
msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
msgstr ""
-#: src/readelf.c:4590
+#: src/readelf.c:4777
#, c-format
msgid ""
"\n"
@@ -1361,33 +1408,33 @@ msgid ""
" %*s String\n"
msgstr ""
-#: src/readelf.c:4603
+#: src/readelf.c:4790
#, c-format
msgid " *** error while reading strings: %s\n"
msgstr ""
-#: src/readelf.c:4628
+#: src/readelf.c:4815
#, c-format
msgid "cannot get debug context descriptor: %s"
msgstr ""
-#: src/readelf.c:4705
+#: src/readelf.c:4893
#, c-format
msgid ""
"\n"
"Note segment of %<PRId64> bytes at offset %#0<PRIx64>:\n"
msgstr ""
-#: src/readelf.c:4712
+#: src/readelf.c:4900
#, c-format
msgid "cannot get content of note section: %s"
msgstr ""
-#: src/readelf.c:4715
+#: src/readelf.c:4903
msgid " Owner Data size Type\n"
msgstr ""
-#: src/readelf.c:4754
+#: src/readelf.c:4943
#, c-format
msgid " %-13.*s %9<PRId32> %s\n"
msgstr ""
@@ -1480,131 +1527,141 @@ msgstr ""
msgid "Embed name FILE instead of -f argument"
msgstr ""
-#: src/strip.c:66
+#: src/strip.c:67
msgid "Remove all debugging symbols"
msgstr ""
-#: src/strip.c:68
+#: src/strip.c:71
msgid "Copy modified/access timestamps to the output"
msgstr ""
-#: src/strip.c:70
+#: src/strip.c:73
msgid "Remove .comment section"
msgstr ""
-#: src/strip.c:72
+#: src/strip.c:76
msgid "Relax a few rules to handle slightly broken ELF files"
msgstr ""
-#: src/strip.c:77
+#: src/strip.c:81
msgid "Discard symbols from object files."
msgstr ""
-#: src/strip.c:169
+#: src/strip.c:173
+#, c-format
msgid "Only one input file allowed together with '-o' and '-f'"
msgstr ""
-#: src/strip.c:206
+#: src/strip.c:209
+#, c-format
msgid "-f option specified twice"
msgstr ""
-#: src/strip.c:215
+#: src/strip.c:218
+#, c-format
msgid "-F option specified twice"
msgstr ""
-#: src/strip.c:224
+#: src/strip.c:227
+#, c-format
msgid "-o option specified twice"
msgstr ""
-#: src/strip.c:266 src/strip.c:290
+#: src/strip.c:247
+msgid "-R option supports only .comment section"
+msgstr ""
+
+#: src/strip.c:285 src/strip.c:309
#, c-format
msgid "cannot stat input file \"%s\""
msgstr ""
-#: src/strip.c:280
+#: src/strip.c:299
#, c-format
msgid "while opening \"%s\""
msgstr ""
-#: src/strip.c:317
+#: src/strip.c:337
#, c-format
msgid "%s: cannot use -o when stripping archive"
msgstr ""
-#: src/strip.c:417
+#: src/strip.c:433
+#, c-format
msgid "cannot open EBL backend"
msgstr ""
-#: src/strip.c:465 src/strip.c:491
+#: src/strip.c:483 src/strip.c:507
#, c-format
msgid "cannot create new file '%s': %s"
msgstr ""
-#: src/strip.c:552
+#: src/strip.c:567
#, c-format
msgid "illformed file '%s'"
msgstr ""
-#: src/strip.c:818 src/strip.c:895
+#: src/strip.c:822 src/strip.c:900
#, c-format
msgid "while generating output file: %s"
msgstr ""
-#: src/strip.c:868 src/strip.c:1602
+#: src/strip.c:873 src/strip.c:1604
#, c-format
msgid "%s: error while creating ELF header: %s"
msgstr ""
-#: src/strip.c:882
+#: src/strip.c:887
#, c-format
msgid "while preparing output for '%s'"
msgstr ""
-#: src/strip.c:936 src/strip.c:992
+#: src/strip.c:938 src/strip.c:994
#, c-format
msgid "while create section header section: %s"
msgstr ""
-#: src/strip.c:942
+#: src/strip.c:944
#, c-format
msgid "cannot allocate section data: %s"
msgstr ""
-#: src/strip.c:1001
+#: src/strip.c:1003
#, c-format
msgid "while create section header string table: %s"
msgstr ""
-#: src/strip.c:1527 src/strip.c:1624
+#: src/strip.c:1529 src/strip.c:1626
#, c-format
msgid "while writing '%s': %s"
msgstr ""
-#: src/strip.c:1538
+#: src/strip.c:1540
#, c-format
msgid "while creating '%s'"
msgstr ""
-#: src/strip.c:1550
+#: src/strip.c:1552
+#, c-format
msgid "while computing checksum for debug information"
msgstr ""
-#: src/strip.c:1610
+#: src/strip.c:1612
#, c-format
msgid "%s: error while reading the file: %s"
msgstr ""
-#: src/strip.c:1652 src/strip.c:1659
+#: src/strip.c:1654 src/strip.c:1661
#, c-format
msgid "error while finishing '%s': %s"
msgstr ""
-#: src/strip.c:1682 src/strip.c:1739
+#: src/strip.c:1684 src/strip.c:1741
#, c-format
msgid "cannot set access and modification date of '%s'"
msgstr ""
-#: src/strip.c:1746
+#: src/strip.c:1748
#, c-format
msgid "while closing '%s'"
msgstr ""
@@ -1819,10 +1876,12 @@ msgid "[FILE]..."
msgstr ""
#: src/ld.c:324
+#, c-format
msgid "At least one input file needed"
msgstr ""
#: src/ld.c:335
+#, c-format
msgid "error while preparing linking"
msgstr ""
@@ -1832,14 +1891,17 @@ msgid "cannot open linker script \"%s\""
msgstr ""
#: src/ld.c:383
+#, c-format
msgid "-( without matching -)"
msgstr ""
#: src/ld.c:508 src/ld.c:546
+#, c-format
msgid "only one option of -G and -r is allowed"
msgstr ""
#: src/ld.c:530
+#, c-format
msgid "more than one '-m' parameter"
msgstr ""
@@ -1854,6 +1916,7 @@ msgid "invalid page size value \"%s\": ignored"
msgstr ""
#: src/ld.c:692
+#, c-format
msgid "More than one output file name given."
msgstr ""
@@ -1863,10 +1926,12 @@ msgid "Invalid optimization level `%s'"
msgstr ""
#: src/ld.c:750
+#, c-format
msgid "nested -( -) groups are not allowed"
msgstr ""
#: src/ld.c:769
+#, c-format
msgid "-) without matching -("
msgstr ""
@@ -1876,10 +1941,12 @@ msgid "unknown option '-%c %s'"
msgstr ""
#: src/ld.c:1044
+#, c-format
msgid "could not find input file to determine output file format"
msgstr ""
#: src/ld.c:1046
+#, c-format
msgid "try again with an appropriate '-m' parameter"
msgstr ""
@@ -1894,6 +1961,7 @@ msgid "duplicate definition of '%s' in linker script"
msgstr ""
#: src/ldgeneric.c:179 src/ldgeneric.c:4464
+#, c-format
msgid "cannot create string table"
msgstr ""
@@ -1989,7 +2057,7 @@ msgstr ""
msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
msgstr ""
-#: src/ldgeneric.c:1593
+#: src/ldgeneric.c:1593 src/elfcmp.c:541
#, c-format
msgid "cannot open \"%s\""
msgstr ""
@@ -2071,6 +2139,7 @@ msgid "cannot create symbol table for output file: %s"
msgstr ""
#: src/ldgeneric.c:4611 src/ldgeneric.c:5138
+#, c-format
msgid "section index too large in dynamic symbol table"
msgstr ""
@@ -2101,6 +2170,7 @@ msgid "cannot create section header string section: %s"
msgstr ""
#: src/ldgeneric.c:5435
+#, c-format
msgid "cannot create section header string section"
msgstr ""
@@ -2115,6 +2185,7 @@ msgid "while determining file layout: %s"
msgstr ""
#: src/ldgeneric.c:5684
+#, c-format
msgid "internal error: nobits section follows nobits section"
msgstr ""
@@ -2129,6 +2200,7 @@ msgid "cannot update ELF header: %s"
msgstr ""
#: src/ldgeneric.c:6217
+#, c-format
msgid "linker backend didn't specify function to relocate section"
msgstr ""
@@ -2143,10 +2215,12 @@ msgid "while finishing output file: %s"
msgstr ""
#: src/ldgeneric.c:6240
+#, c-format
msgid "cannot stat output file"
msgstr ""
#: src/ldgeneric.c:6256
+#, c-format
msgid "WARNING: temporary output file overwritten before linking finished"
msgstr ""
@@ -2181,6 +2255,7 @@ msgid "symbol '%s' in declared both local and global for version '%s'"
msgstr ""
#: src/ldscript.y:748 src/ldscript.y:755
+#, c-format
msgid "default visibility set as local and global"
msgstr ""
@@ -2215,6 +2290,11 @@ msgstr ""
msgid "No errors"
msgstr ""
+#: src/elflint.c:291
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr ""
+
#: src/elflint.c:350
#, c-format
msgid "e_ident[%d] == %d is no known class\n"
@@ -2256,877 +2336,1154 @@ msgid "unknown machine type %d\n"
msgstr ""
#: src/elflint.c:391
+#, c-format
msgid "unknown object file version\n"
msgstr ""
#: src/elflint.c:397
+#, c-format
msgid "invalid program header offset\n"
msgstr ""
#: src/elflint.c:399
+#, c-format
msgid "executables and DSOs cannot have zero program header offset\n"
msgstr ""
#: src/elflint.c:403
+#, c-format
msgid "invalid number of program header entries\n"
msgstr ""
#: src/elflint.c:411
+#, c-format
msgid "invalid section header table offset\n"
msgstr ""
#: src/elflint.c:414
+#, c-format
msgid "section header table must be present\n"
msgstr ""
-#: src/elflint.c:430
+#: src/elflint.c:428
+#, c-format
msgid "invalid number of section header table entries\n"
msgstr ""
-#: src/elflint.c:449 src/elflint.c:455
+#: src/elflint.c:445
+#, c-format
msgid "invalid section header index\n"
msgstr ""
-#: src/elflint.c:460
+#: src/elflint.c:450
#, c-format
msgid "invalid machine flags: %s\n"
msgstr ""
-#: src/elflint.c:467 src/elflint.c:484
+#: src/elflint.c:457 src/elflint.c:474
#, c-format
msgid "invalid ELF header size: %hd\n"
msgstr ""
-#: src/elflint.c:470 src/elflint.c:487
+#: src/elflint.c:460 src/elflint.c:477
#, c-format
msgid "invalid program header size: %hd\n"
msgstr ""
-#: src/elflint.c:473 src/elflint.c:490
+#: src/elflint.c:463 src/elflint.c:480
+#, c-format
msgid "invalid program header position or size\n"
msgstr ""
-#: src/elflint.c:476 src/elflint.c:493
+#: src/elflint.c:466 src/elflint.c:483
#, c-format
msgid "invalid section header size: %hd\n"
msgstr ""
-#: src/elflint.c:479 src/elflint.c:496
+#: src/elflint.c:469 src/elflint.c:486
+#, c-format
msgid "invalid section header position or size\n"
msgstr ""
-#: src/elflint.c:545
+#: src/elflint.c:530
#, c-format
msgid ""
"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
"group\n"
msgstr ""
-#: src/elflint.c:549
+#: src/elflint.c:534
#, c-format
msgid ""
"section [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"
msgstr ""
-#: src/elflint.c:574 src/elflint.c:1010 src/elflint.c:1145 src/elflint.c:1332
-#: src/elflint.c:1579
+#: src/elflint.c:550 src/elflint.c:1243 src/elflint.c:1292 src/elflint.c:1399
+#: src/elflint.c:1629 src/elflint.c:2003 src/elflint.c:2164 src/elflint.c:2294
#, c-format
msgid "section [%2d] '%s': cannot get section data\n"
msgstr ""
-#: src/elflint.c:580 src/elflint.c:1339
+#: src/elflint.c:562 src/elflint.c:1406
#, c-format
msgid ""
"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
"type is not SHT_STRTAB\n"
msgstr ""
-#: src/elflint.c:612
+#: src/elflint.c:584
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:595
#, c-format
msgid "section [%2zu] '%s': entry size is does not match ElfXX_Sym\n"
msgstr ""
-#: src/elflint.c:621
+#: src/elflint.c:604
#, c-format
msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
msgstr ""
-#: src/elflint.c:626 src/elflint.c:629 src/elflint.c:632 src/elflint.c:635
-#: src/elflint.c:638 src/elflint.c:641
+#: src/elflint.c:609 src/elflint.c:612 src/elflint.c:615 src/elflint.c:618
+#: src/elflint.c:621 src/elflint.c:624
#, c-format
msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
msgstr ""
-#: src/elflint.c:644
+#: src/elflint.c:627
#, c-format
msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
msgstr ""
-#: src/elflint.c:654
+#: src/elflint.c:637
#, c-format
msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
msgstr ""
-#: src/elflint.c:661
+#: src/elflint.c:644
#, c-format
msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
msgstr ""
-#: src/elflint.c:674
+#: src/elflint.c:657
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: too large section index but no extended "
"section index section\n"
msgstr ""
-#: src/elflint.c:680
+#: src/elflint.c:663
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
"st_shndx (%<PRIu32>)\n"
msgstr ""
-#: src/elflint.c:692
+#: src/elflint.c:675
#, c-format
msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
msgstr ""
-#: src/elflint.c:699
+#: src/elflint.c:683
#, c-format
msgid "section [%2d] '%s': symbol %zu: unknown type\n"
msgstr ""
-#: src/elflint.c:703
+#: src/elflint.c:687
#, c-format
msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
msgstr ""
-#: src/elflint.c:711
+#: src/elflint.c:695
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
msgstr ""
-#: src/elflint.c:715
+#: src/elflint.c:699
#, c-format
msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
msgstr ""
-#: src/elflint.c:719
+#: src/elflint.c:703
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
msgstr ""
-#: src/elflint.c:734
+#: src/elflint.c:722
#, c-format
msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
msgstr ""
-#: src/elflint.c:739 src/elflint.c:763 src/elflint.c:806
+#: src/elflint.c:727 src/elflint.c:752 src/elflint.c:795
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
"[%2d] '%s'\n"
msgstr ""
-#: src/elflint.c:747
+#: src/elflint.c:736
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
"SHF_TLS flag set\n"
msgstr ""
-#: src/elflint.c:757 src/elflint.c:799
+#: src/elflint.c:746 src/elflint.c:788
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
"[%2d] '%s'\n"
msgstr ""
-#: src/elflint.c:784
+#: src/elflint.c:773
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
msgstr ""
-#: src/elflint.c:792
+#: src/elflint.c:781
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%"
"s'\n"
msgstr ""
-#: src/elflint.c:819
+#: src/elflint.c:808
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: local symbol outside range described in "
"sh_info\n"
msgstr ""
-#: src/elflint.c:826
+#: src/elflint.c:815
#, c-format
msgid ""
"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
"sh_info\n"
msgstr ""
-#: src/elflint.c:833
+#: src/elflint.c:822
#, c-format
msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
msgstr ""
-#: src/elflint.c:884
+#: src/elflint.c:869
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section\n"
+msgstr ""
+
+#: src/elflint.c:874
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to '%s' section\n"
+msgstr ""
+
+#: src/elflint.c:888
#, c-format
msgid ""
"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
-"match .got section address %#<PRIx64>\n"
+"match %s section address %#<PRIx64>\n"
msgstr ""
-#: src/elflint.c:890
+#: src/elflint.c:895
#, c-format
msgid ""
"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
-"match .got section size %<PRIu64>\n"
+"match %s section size %<PRIu64>\n"
msgstr ""
-#: src/elflint.c:896
+#: src/elflint.c:903
#, c-format
msgid ""
"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
"section\n"
msgstr ""
-#: src/elflint.c:915
+#: src/elflint.c:919
#, c-format
msgid ""
"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
"segment address %#<PRIx64>\n"
msgstr ""
-#: src/elflint.c:922
+#: src/elflint.c:926
#, c-format
msgid ""
"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
"segment size %<PRIu64>\n"
msgstr ""
-#: src/elflint.c:975
+#: src/elflint.c:979
#, c-format
msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
msgstr ""
-#: src/elflint.c:1017 src/elflint.c:1152
+#: src/elflint.c:1019
#, c-format
msgid "section [%2d] '%s': invalid destination section index\n"
msgstr ""
-#: src/elflint.c:1030 src/elflint.c:1165
+#: src/elflint.c:1032
#, c-format
msgid "section [%2d] '%s': invalid destination section type\n"
msgstr ""
-#: src/elflint.c:1038 src/elflint.c:1173
+#: src/elflint.c:1040
#, c-format
msgid "section [%2d] '%s': sh_info should be zero\n"
msgstr ""
-#: src/elflint.c:1045 src/elflint.c:1180
+#: src/elflint.c:1047
#, c-format
msgid "section [%2d] '%s': no relocations for merge-able sections possible\n"
msgstr ""
-#: src/elflint.c:1052
+#: src/elflint.c:1054
#, c-format
msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
msgstr ""
-#: src/elflint.c:1069 src/elflint.c:1204
+#: src/elflint.c:1055
#, c-format
-msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rel\n"
msgstr ""
-#: src/elflint.c:1076 src/elflint.c:1211
+#: src/elflint.c:1114
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+
+#: src/elflint.c:1140
#, c-format
msgid "section [%2d] '%s': relocation %zu: invalid type\n"
msgstr ""
-#: src/elflint.c:1079 src/elflint.c:1214
+#: src/elflint.c:1143
#, c-format
msgid ""
"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
"type\n"
msgstr ""
-#: src/elflint.c:1087 src/elflint.c:1222
+#: src/elflint.c:1151
#, c-format
msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
msgstr ""
-#: src/elflint.c:1102 src/elflint.c:1237
+#: src/elflint.c:1165
#, c-format
msgid ""
"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
"be used with %s\n"
msgstr ""
-#: src/elflint.c:1117 src/elflint.c:1253
+#: src/elflint.c:1181
#, c-format
msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
msgstr ""
-#: src/elflint.c:1187
+#: src/elflint.c:1196
#, c-format
-msgid "section [%2d] '%s': section entry size does not match ElfXX_Rel\n"
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type %"
+"s\n"
+msgstr ""
+
+#: src/elflint.c:1214
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+
+#: src/elflint.c:1229
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+
+#: src/elflint.c:1267 src/elflint.c:1316
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
msgstr ""
-#: src/elflint.c:1323
+#: src/elflint.c:1394
+#, c-format
msgid "more than one dynamic section present\n"
msgstr ""
-#: src/elflint.c:1345
+#: src/elflint.c:1412
#, c-format
msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
msgstr ""
-#: src/elflint.c:1350 src/elflint.c:1512
+#: src/elflint.c:1417 src/elflint.c:1569
#, c-format
msgid "section [%2d] '%s': sh_info not zero\n"
msgstr ""
-#: src/elflint.c:1362
+#: src/elflint.c:1427
#, c-format
msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
msgstr ""
-#: src/elflint.c:1370
+#: src/elflint.c:1435
#, c-format
msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
msgstr ""
-#: src/elflint.c:1377
+#: src/elflint.c:1442
#, c-format
msgid "section [%2d] '%s': entry %zu: unknown tag\n"
msgstr ""
-#: src/elflint.c:1388
+#: src/elflint.c:1453
#, c-format
msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
msgstr ""
-#: src/elflint.c:1398
+#: src/elflint.c:1463
#, c-format
msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
msgstr ""
-#: src/elflint.c:1410
+#: src/elflint.c:1475
#, c-format
msgid ""
"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
msgstr ""
-#: src/elflint.c:1435
+#: src/elflint.c:1498
#, c-format
msgid "section [%2d] '%s': contains %s entry but not %s\n"
msgstr ""
-#: src/elflint.c:1447
+#: src/elflint.c:1510
#, c-format
msgid "section [%2d] '%s': mandatory tag %s not present\n"
msgstr ""
-#: src/elflint.c:1457 src/elflint.c:1464
+#: src/elflint.c:1520 src/elflint.c:1527
#, c-format
msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
msgstr ""
-#: src/elflint.c:1492
+#: src/elflint.c:1539
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1549
#, c-format
msgid ""
"section [%2d] '%s': extended section index section not for symbol table\n"
msgstr ""
-#: src/elflint.c:1497
+#: src/elflint.c:1554
+#, c-format
msgid "cannot get data for symbol section\n"
msgstr ""
-#: src/elflint.c:1500 src/elflint.c:1591
+#: src/elflint.c:1557 src/elflint.c:1643
#, c-format
msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
msgstr ""
-#: src/elflint.c:1507
+#: src/elflint.c:1564
#, c-format
msgid "section [%2d] '%s': extended index table too small for symbol table\n"
msgstr ""
-#: src/elflint.c:1524
+#: src/elflint.c:1579
#, c-format
msgid ""
"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
"same symbol table\n"
msgstr ""
-#: src/elflint.c:1535
+#: src/elflint.c:1590
+#, c-format
msgid "symbol 0 should have zero extended section index\n"
msgstr ""
-#: src/elflint.c:1547
+#: src/elflint.c:1602
#, c-format
msgid "cannot get data for symbol %zu\n"
msgstr ""
-#: src/elflint.c:1552
+#: src/elflint.c:1607
#, c-format
msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
msgstr ""
-#: src/elflint.c:1586
+#: src/elflint.c:1620
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:1638
#, c-format
msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
msgstr ""
-#: src/elflint.c:1596
+#: src/elflint.c:1648
#, c-format
msgid "section [%2d] '%s': not marked to be allocated\n"
msgstr ""
-#: src/elflint.c:1601
+#: src/elflint.c:1653
#, c-format
msgid ""
"section [%2d] '%s': hash table has not even room for nbucket and nchain\n"
msgstr ""
-#: src/elflint.c:1611
+#: src/elflint.c:1663
#, c-format
msgid ""
"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
msgstr ""
-#: src/elflint.c:1622
+#: src/elflint.c:1674
#, c-format
msgid "section [%2d] '%s': chain array not large enough\n"
msgstr ""
-#: src/elflint.c:1627
+#: src/elflint.c:1679
#, c-format
msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
msgstr ""
-#: src/elflint.c:1633
+#: src/elflint.c:1685
#, c-format
msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
msgstr ""
-#: src/elflint.c:1645
+#: src/elflint.c:1697
#, c-format
msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
msgstr ""
-#: src/elflint.c:1665
+#: src/elflint.c:1717
#, c-format
msgid ""
"section [%2d] '%s': section groups only allowed in relocatable object files\n"
msgstr ""
-#: src/elflint.c:1676
+#: src/elflint.c:1728
#, c-format
msgid "section [%2d] '%s': cannot get symbol table: %s\n"
msgstr ""
-#: src/elflint.c:1681
+#: src/elflint.c:1733
#, c-format
msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
msgstr ""
-#: src/elflint.c:1687
+#: src/elflint.c:1739
#, c-format
msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
msgstr ""
-#: src/elflint.c:1692
+#: src/elflint.c:1744
#, c-format
msgid "section [%2d] '%s': sh_flags not zero\n"
msgstr ""
-#: src/elflint.c:1697
+#: src/elflint.c:1749
#, c-format
msgid "section [%2d] '%s': sh_flags not set correctly\n"
msgstr ""
-#: src/elflint.c:1703
+#: src/elflint.c:1755
#, c-format
msgid "section [%2d] '%s': cannot get data: %s\n"
msgstr ""
-#: src/elflint.c:1712
+#: src/elflint.c:1764
#, c-format
msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
msgstr ""
-#: src/elflint.c:1717
+#: src/elflint.c:1769
#, c-format
msgid "section [%2d] '%s': section group without flags word\n"
msgstr ""
-#: src/elflint.c:1723
+#: src/elflint.c:1775
#, c-format
msgid "section [%2d] '%s': section group without member\n"
msgstr ""
-#: src/elflint.c:1727
+#: src/elflint.c:1779
#, c-format
msgid "section [%2d] '%s': section group with only one member\n"
msgstr ""
-#: src/elflint.c:1738
+#: src/elflint.c:1790
#, c-format
msgid "section [%2d] '%s': unknown section group flags\n"
msgstr ""
-#: src/elflint.c:1750
+#: src/elflint.c:1802
#, c-format
msgid "section [%2d] '%s': section index %Zu out of range\n"
msgstr ""
-#: src/elflint.c:1761
+#: src/elflint.c:1811
#, c-format
msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
msgstr ""
-#: src/elflint.c:1768
+#: src/elflint.c:1818
#, c-format
msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
msgstr ""
-#: src/elflint.c:1774
+#: src/elflint.c:1824
#, c-format
msgid ""
"section [%2d] '%s': element %Zu references section [%2d] '%s' without "
"SHF_GROUP flag set\n"
msgstr ""
-#: src/elflint.c:1781
+#: src/elflint.c:1831
#, c-format
msgid "section [%2d] '%s' is contained in more than one section group\n"
msgstr ""
-#: src/elflint.c:1906
+#: src/elflint.c:2017
#, c-format
msgid ""
"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
"dynamic symbol table\n"
msgstr ""
-#: src/elflint.c:1915
+#: src/elflint.c:2028
#, c-format
msgid ""
"section [%2d] '%s' has different number of entries than symbol table [%2d] '%"
"s'\n"
msgstr ""
-#: src/elflint.c:1947
+#: src/elflint.c:2044
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2060
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2068
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:2082
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:2087
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:2097
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:2149
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:2157 src/elflint.c:2286
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:2180 src/elflint.c:2338
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:2186 src/elflint.c:2344
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2194
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:2202
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:2214
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:2221
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:2228
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %"
+"#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:2238
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2249
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:2265 src/elflint.c:2423
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:2278
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:2323
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:2327
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:2333
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:2357
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:2364
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:2373
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2392
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2407
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2429
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:2445
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2525
+#, c-format
msgid "cannot get section header of zeroth section\n"
msgstr ""
-#: src/elflint.c:1951
+#: src/elflint.c:2529
+#, c-format
msgid "zeroth section has nonzero name\n"
msgstr ""
-#: src/elflint.c:1953
+#: src/elflint.c:2531
+#, c-format
msgid "zeroth section has nonzero type\n"
msgstr ""
-#: src/elflint.c:1955
+#: src/elflint.c:2533
+#, c-format
msgid "zeroth section has nonzero flags\n"
msgstr ""
-#: src/elflint.c:1957
+#: src/elflint.c:2535
+#, c-format
msgid "zeroth section has nonzero address\n"
msgstr ""
-#: src/elflint.c:1959
+#: src/elflint.c:2537
+#, c-format
msgid "zeroth section has nonzero offset\n"
msgstr ""
-#: src/elflint.c:1961
+#: src/elflint.c:2539
+#, c-format
msgid "zeroth section has nonzero info field\n"
msgstr ""
-#: src/elflint.c:1963
+#: src/elflint.c:2541
+#, c-format
msgid "zeroth section has nonzero align value\n"
msgstr ""
-#: src/elflint.c:1965
+#: src/elflint.c:2543
+#, c-format
msgid "zeroth section has nonzero entry size value\n"
msgstr ""
-#: src/elflint.c:1968
+#: src/elflint.c:2546
+#, c-format
msgid ""
"zeroth section has nonzero size value while ELF header has nonzero shnum "
"value\n"
msgstr ""
-#: src/elflint.c:1972
+#: src/elflint.c:2550
+#, c-format
msgid ""
"zeroth section has nonzero link value while ELF header does not signal "
"overflow in shstrndx\n"
msgstr ""
-#: src/elflint.c:1984
+#: src/elflint.c:2562
#, c-format
msgid "cannot get section header for section [%2zu] '%s': %s\n"
msgstr ""
-#: src/elflint.c:1993
+#: src/elflint.c:2571
#, c-format
msgid "section [%2zu]: invalid name\n"
msgstr ""
-#: src/elflint.c:2009
+#: src/elflint.c:2593
#, c-format
msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
msgstr ""
-#: src/elflint.c:2023
+#: src/elflint.c:2607
#, c-format
msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
msgstr ""
-#: src/elflint.c:2040
+#: src/elflint.c:2624
#, c-format
msgid ""
"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
msgstr ""
-#: src/elflint.c:2058
+#: src/elflint.c:2642
#, c-format
msgid "section [%2zu] '%s' present in object file\n"
msgstr ""
-#: src/elflint.c:2064 src/elflint.c:2096
+#: src/elflint.c:2648 src/elflint.c:2680
#, c-format
msgid ""
"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
msgstr ""
-#: src/elflint.c:2069 src/elflint.c:2101
+#: src/elflint.c:2653 src/elflint.c:2685
#, c-format
msgid ""
"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
"segments\n"
msgstr ""
-#: src/elflint.c:2077
+#: src/elflint.c:2661
#, c-format
msgid ""
"section [%2zu] '%s' is extension section index table in non-object file\n"
msgstr ""
-#: src/elflint.c:2112
+#: src/elflint.c:2696
#, c-format
msgid "section [%2zu] '%s': size not multiple of entry size\n"
msgstr ""
-#: src/elflint.c:2117
+#: src/elflint.c:2701
+#, c-format
msgid "cannot get section header\n"
msgstr ""
-#: src/elflint.c:2125
+#: src/elflint.c:2710
#, c-format
-msgid "unsupported section type %d\n"
+msgid "section [%2zu] '%s' has unsupported type %d\n"
msgstr ""
-#: src/elflint.c:2131
+#: src/elflint.c:2718
#, c-format
-msgid "section [%2zu] '%s' contain unknown flag(s) %d\n"
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
msgstr ""
-#: src/elflint.c:2138
+#: src/elflint.c:2726
#, c-format
msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
msgstr ""
-#: src/elflint.c:2146
+#: src/elflint.c:2734
#, c-format
msgid "section [%2zu] '%s': invalid section reference in link value\n"
msgstr ""
-#: src/elflint.c:2151
+#: src/elflint.c:2739
#, c-format
msgid "section [%2zu] '%s': invalid section reference in info value\n"
msgstr ""
-#: src/elflint.c:2158
+#: src/elflint.c:2746
#, c-format
msgid "section [%2zu] '%s': strings flag set without merge flag\n"
msgstr ""
-#: src/elflint.c:2163
+#: src/elflint.c:2751
#, c-format
msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
msgstr ""
-#: src/elflint.c:2190
+#: src/elflint.c:2778
#, c-format
msgid ""
"section [%2zu] '%s' not fully contained in segment of program header entry %"
"d\n"
msgstr ""
-#: src/elflint.c:2198
+#: src/elflint.c:2786
#, c-format
msgid ""
"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
"program header entry %d\n"
msgstr ""
-#: src/elflint.c:2205
+#: src/elflint.c:2795
#, c-format
msgid ""
"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
"segment of program header entry %d\n"
msgstr ""
-#: src/elflint.c:2214
+#: src/elflint.c:2804
#, c-format
msgid ""
"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
msgstr ""
-#: src/elflint.c:2220
+#: src/elflint.c:2810
#, c-format
msgid ""
"section [%2zu] '%s': ELF header says this is the section header string table "
"but type is not SHT_TYPE\n"
msgstr ""
-#: src/elflint.c:2270
+#: src/elflint.c:2818
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:2859
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:2878
+#, c-format
msgid "INTERP program header entry but no .interp section\n"
msgstr ""
-#: src/elflint.c:2281
+#: src/elflint.c:2883
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:2896
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:2910
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:2922
#, c-format
msgid "phdr[%d]: no note entries defined for the type of file\n"
msgstr ""
-#: src/elflint.c:2368
+#: src/elflint.c:3009
#, c-format
msgid "phdr[%d]: note entries probably in form of a 32-bit ELF file\n"
msgstr ""
-#: src/elflint.c:2371
+#: src/elflint.c:3012
#, c-format
msgid "phdr[%d]: extra %zu bytes after last note\n"
msgstr ""
-#: src/elflint.c:2400
+#: src/elflint.c:3041
#, c-format
msgid "phdr[%d]: unknown core file note type %<PRIu64> at offset %<PRIu64>\n"
msgstr ""
-#: src/elflint.c:2408
+#: src/elflint.c:3049
#, c-format
msgid "phdr[%d]: unknown object file note type %<PRIu64> at offset %<PRIu64>\n"
msgstr ""
-#: src/elflint.c:2430
+#: src/elflint.c:3071
+#, c-format
msgid ""
"only executables, shared objects, and core files can have program headers\n"
msgstr ""
-#: src/elflint.c:2445
+#: src/elflint.c:3086
#, c-format
msgid "cannot get program header entry %d: %s\n"
msgstr ""
-#: src/elflint.c:2452
+#: src/elflint.c:3095
#, c-format
-msgid "program header entry %d: unknown program header entry type\n"
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
msgstr ""
-#: src/elflint.c:2463
+#: src/elflint.c:3106
+#, c-format
msgid "more than one INTERP entry in program header\n"
msgstr ""
-#: src/elflint.c:2471
+#: src/elflint.c:3114
+#, c-format
msgid "more than one TLS entry in program header\n"
msgstr ""
-#: src/elflint.c:2477
+#: src/elflint.c:3121
+#, c-format
msgid "static executable cannot have dynamic sections\n"
msgstr ""
-#: src/elflint.c:2481
+#: src/elflint.c:3135
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:3138
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:3148
+#, c-format
msgid "more than one GNU_RELRO entry in program header\n"
msgstr ""
-#: src/elflint.c:2502
+#: src/elflint.c:3169
+#, c-format
msgid "loadable segment GNU_RELRO applies to is not writable\n"
msgstr ""
-#: src/elflint.c:2505
+#: src/elflint.c:3172
+#, c-format
msgid "loadable segment GNU_RELRO applies to is executable\n"
msgstr ""
-#: src/elflint.c:2512
+#: src/elflint.c:3179
+#, c-format
msgid "GNU_RELRO segment not contained in a loaded segment\n"
msgstr ""
-#: src/elflint.c:2518
+#: src/elflint.c:3185
#, c-format
msgid "program header entry %d: file size greater than memory size\n"
msgstr ""
-#: src/elflint.c:2525
+#: src/elflint.c:3192
#, c-format
msgid "program header entry %d: alignment not a power of 2\n"
msgstr ""
-#: src/elflint.c:2528
+#: src/elflint.c:3195
#, c-format
msgid ""
"program header entry %d: file offset and virtual address not module of "
"alignment\n"
msgstr ""
-#: src/elflint.c:2558
+#: src/elflint.c:3231
#, c-format
msgid "cannot read ELF header: %s\n"
msgstr ""
-#: src/addr2line.c:52 src/findtextrel.c:56
-msgid "Input Selection:"
-msgstr ""
-
-#: src/addr2line.c:53
-msgid "Find addresses in FILE"
+#: src/elflint.c:3252
+#, c-format
+msgid "text relocation flag set but not needed\n"
msgstr ""
-#: src/addr2line.c:55
+#: src/addr2line.c:52
msgid "Output Selection:"
msgstr ""
-#: src/addr2line.c:56
+#: src/addr2line.c:53
msgid "Show only base names of source files"
msgstr ""
-#: src/addr2line.c:57
+#: src/addr2line.c:54
msgid "Additional show function names"
msgstr ""
-#: src/addr2line.c:68
+#: src/addr2line.c:65
msgid ""
"Locate source files and line information for ADDRs (in a.out by default)."
msgstr ""
-#: src/addr2line.c:72
+#: src/addr2line.c:69
msgid "[ADDR...]"
msgstr ""
-#: src/addr2line.c:135
-#, c-format
-msgid "cannot create ELF descriptor: %s"
+#: src/findtextrel.c:56
+msgid "Input Selection:"
msgstr ""
#: src/findtextrel.c:57
@@ -3141,7 +3498,7 @@ msgstr ""
msgid "Locate source of text relocations in FILEs (a.out by default)."
msgstr ""
-#: src/findtextrel.c:222
+#: src/findtextrel.c:222 src/ranlib.c:310
#, c-format
msgid "cannot create ELF descriptor for '%s': %s"
msgstr ""
@@ -3172,6 +3529,7 @@ msgid "no text relocations reported in '%s'"
msgstr ""
#: src/findtextrel.c:305
+#, c-format
msgid "while reading ELF file"
msgstr ""
@@ -3225,3 +3583,162 @@ msgstr ""
msgid ""
"a relocation modifies memory at offset %llu in a write-protected segment\n"
msgstr ""
+
+#: src/elfcmp.c:55
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:56
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:57
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#: src/elfcmp.c:64
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#: src/elfcmp.c:68
+msgid "FILE1 FILE2"
+msgstr ""
+
+#: src/elfcmp.c:119
+msgid "Invalid number of parameters.\n"
+msgstr ""
+
+#: src/elfcmp.c:147 src/elfcmp.c:152
+#, c-format
+msgid "cannot get ELF header of \"%s\": %s"
+msgstr ""
+
+#: src/elfcmp.c:169
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:227
+#, c-format
+msgid "%s %s differ: section header"
+msgstr ""
+
+#: src/elfcmp.c:253 src/elfcmp.c:259
+#, c-format
+msgid "cannot get content of section %zu in \"%s\": %s"
+msgstr ""
+
+#: src/elfcmp.c:275 src/elfcmp.c:281
+#, c-format
+msgid "cannot get symbol in \"%s\": %s"
+msgstr ""
+
+#: src/elfcmp.c:302
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:305
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:346
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:351
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:367
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:401 src/elfcmp.c:406
+#, c-format
+msgid "cannot load data of \"%s\": %s"
+msgstr ""
+
+#: src/elfcmp.c:425 src/elfcmp.c:431
+#, c-format
+msgid "cannot get program header entry %d of \"%s\": %s"
+msgstr ""
+
+#: src/elfcmp.c:437
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:462
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:521
+#, c-format
+msgid "Invalid value \"%s\" for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:545
+#, c-format
+msgid "cannot create ELF descriptor for \"%s\": %s"
+msgstr ""
+
+#: src/elfcmp.c:550
+#, c-format
+msgid "cannot create EBL descriptor for \"%s\""
+msgstr ""
+
+#: src/elfcmp.c:568
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:578
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:588 src/elfcmp.c:602
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/ranlib.c:74
+msgid "Generate an index to speed access to archives."
+msgstr ""
+
+#: src/ranlib.c:77
+msgid "ARCHIVE"
+msgstr ""
+
+#: src/ranlib.c:119
+#, c-format
+msgid "Archive name required"
+msgstr ""
+
+#: src/ranlib.c:175
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr ""
+
+#: src/ranlib.c:300
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: src/ranlib.c:318
+#, c-format
+msgid "'%s' is no archive"
+msgstr ""
+
+#: src/ranlib.c:397
+#, c-format
+msgid "cannot create new file"
+msgstr ""
diff --git a/elfutils/src/ChangeLog b/elfutils/src/ChangeLog
index b55e43b6..7707ac17 100644
--- a/elfutils/src/ChangeLog
+++ b/elfutils/src/ChangeLog
@@ -1,3 +1,217 @@
+2005-08-24 Ulrich Drepper <drepper@redhat.com>
+
+ * elflint.c (check_versym): Versioned symbols should not have
+ local binding.
+
+2005-08-15 Ulrich Drepper <drepper@redhat.com>
+
+ * elflint.c (check_versym): Allow VER_NDX_LOCAL symbols to be
+ undefined.
+
+ * Makefile.am: Add rules to build ranlib.
+ * ranlib.c: New file.
+
+2005-08-14 Roland McGrath <roland@redhat.com>
+
+ * elflint.c (check_sections): Use ebl_section_type_name and allow any
+ sh_type it recognizes.
+
+ * elflint.c (check_sections): Print unknown flags in hex, don't
+ truncate high bits. Print section number and name for unknown type.
+
+2005-08-13 Roland McGrath <roland@redhat.com>
+
+ * elflint.c (check_program_header): Use ebl_segment_type_name and
+ allow any p_type it recognizes. Include p_type value in error
+ message for unknown type.
+
+2005-08-13 Ulrich Drepper <drepper@redhat.com>
+
+ * elflint.c (check_symtab): Simplify last change a bit. Pass ehdr
+ to ebl_check_special_symbol.
+ (check_sections): Pass ehdr to ebl_bss_plt_p.
+
+2005-08-12 Roland McGrath <roland@redhat.com>
+
+ * elflint.c (check_symtab): Check that _GLOBAL_OFFSET_TABLE_ st_shndx
+ refers to the right section if it's not SHN_ABS.
+ Let ebl_check_special_symbol override _G_O_T_ value and size checks.
+
+ * elflint.c (check_sections): Don't complain about a non-NOBITS
+ section taking no segment space, if it's sh_size is 0.
+
+ * elflint.c (check_sections): Use ebl_bss_plt_p to see if .plt should
+ be PROGBITS or NOBITS.
+
+ * elflint.c (check_symtab): Use ebl_check_special_symbol to override
+ standard st_value and st_size checks.
+
+2005-07-28 Roland McGrath <roland@redhat.com>
+
+ * addr2line.c (options, parse_opt): Don't handle -e here.
+ (executable): Variable removed.
+ (argp_children): New static variable.
+ (argp): Use it. Make const.
+ (main): Fill in argp_children from dwfl_standard_argp ().
+ Let libdwfl handle file selection, pass Dwfl handle to handle_address.
+ (print_dwarf_function): New function. Try to figure out inline chain.
+ (elf_getname): Function removed, libdwfl does it for us.
+ (handle_address): Take Dwfl handle instead of Elf, Dwarf handles.
+ Use dwfl_module_addrname instead of elf_getname.
+ Use dwfl_module_getsrc and dwfl_lineinfo instead of libdw calls.
+ * Makefile.am (INCLUDES): Add libdwfl directory to path.
+
+2005-08-10 Ulrich Drepper <drepper@redhat.com>
+
+ * strip.c (parse_opt): STATE parameter is now used.
+ Various little cleanups.
+
+ * readelf.c (print_debug_line_section): Correct fallout of renaming
+ of DW_LNS_set_epilog_begin.
+
+2005-08-08 Roland McGrath <roland@redhat.com>
+
+ * strip.c (options, parse_opt): Grok -R .comment for compatibility
+ with binutils strip. Likewise -d, -S, as aliases for -g.
+ Likewise ignore -s/--strip-all.
+
+2005-08-07 Roland McGrath <roland@redhat.com>
+
+ * strip.c (process_file): Open read-only when using a different output
+ file.
+
+2005-08-06 Ulrich Drepper <drepper@redhat.com>
+
+ * elflint.c (in_nobits_scn): New function.
+ (check_versym): Allow references for defined symbols against versions
+ of other DSOs also for symbols in nobits sections.
+ Move a few variables around.
+
+ * Makefile.am (AM_CFLAGS): Avoid duplication.
+ Link with statis libs if BUILD_STATIC.
+
+2005-08-05 Ulrich Drepper <drepper@redhat.com>
+
+ * elflint.c: Many, many more tests. Mostly related to symbol
+ versioning. Those sections should now be completely checked.
+
+ * readelf.c (print_dynamic): Use gelf_offscn.
+
+2005-08-04 Ulrich Drepper <drepper@redhat.com>
+
+ * elflint.c: Add lots more tests: more extension symbol table sanity,
+ versioning section tests, hash table tests. General cleanup.
+
+2005-08-02 Ulrich Drepper <drepper@redhat.com>
+
+ * objdump.c: New file.
+ * Makefile.am (bin_PROGRAMS): Add objdump.
+ (objdump_LDADD): Define.
+
+ * elflint.c (check_reloc_shdr): New function split out from check_rela
+ and check_rel.
+ (check_one_reloc): New function. Likewise.
+ (check_rela): Use check_reloc_shdr and check_one_reloc.
+ (check_rel): Likewise.
+ (check_program_header): Check that PT_DYNAMIC entry matches .dynamic
+ section.
+ Add checks that relocations against read-only segments are flagged,
+ that the text relocation flag is not set unnecessarily, and that
+ relocations in one section are either against loaded or not-loaded
+ segments.
+
+2005-08-01 Ulrich Drepper <drepper@redhat.com>
+
+ * elfcmp.c (main): Ignore section count and section name string table
+ section index.
+
+2005-07-27 Roland McGrath <roland@redhat.com>
+
+ * elfcmp.c: Include <locale.h>.
+
+2005-07-27 Ulrich Drepper <drepper@redhat.com>
+
+ * elfcmp.c: Print name and index of differing section.
+
+2005-07-24 Ulrich Drepper <drepper@redhat.com>
+
+ * elfcmp.c: Implement comparing gaps between sections.
+
+2005-07-23 Ulrich Drepper <drepper@redhat.com>
+
+ * elflint.c: Include libeblP.h instead of libebl.h.
+ * nm.c: Likewise.
+ * readelf.c: Likewise.
+ * elfcmp.c: Likewise.
+
+ * elfcmp.c (main): Compare individual ELF header fields, excluding
+ e_shoff instead of the whole struct at once.
+ Use ebl_section_strip_p instead of SECTION_STRIP_P.
+ * strip.c: Use ebl_section_strip_p instead of SECTION_STRIP_P.
+
+2005-07-22 Ulrich Drepper <drepper@redhat.com>
+
+ * elfcmp.c (main): Take empty section into account when comparing
+ section content.
+
+ * elflint.c (check_dynamic): Check that d_tag value is >= 0 before
+ using it.
+
+2005-07-21 Ulrich Drepper <drepper@redhat.com>
+
+ * elfcmp.c: New file.
+ * Makefile.am (bin_PROGRAMS): Add elfcmp.
+ (elfcmp_LDADD): Define.
+
+ * elflint.c (check_rela): Check that copy relocations only reference
+ object symbols or symbols with unknown type.
+ (check_rel): Likewise.
+
+2005-06-08 Roland McGrath <roland@redhat.com>
+
+ * readelf.c (print_ops): Add consts.
+
+2005-05-31 Roland McGrath <roland@redhat.com>
+
+ * readelf.c (print_debug_abbrev_section): Don't bail after first CU's
+ abbreviations. Print a header line before each CU section.
+
+ * readelf.c (print_debug_loc_section): Fix indentation for larger
+ address size.
+
+2005-05-30 Roland McGrath <roland@redhat.com>
+
+ * readelf.c (print_debug_line_section): Print section offset of each
+ CU's table, so they are easy to find from seeing the stmt_list value.
+
+ * readelf.c (dwarf_attr_string): Add all attributes in <dwarf.h>.
+ (attr_callback): Grok DW_AT_ranges and print offset in hex.
+
+ * readelf.c (attr_callback): Add 2 to addrsize * 2 for %#0* format.
+ (print_debug_ranges_section, print_debug_loc_section): Likewise.
+
+ * readelf.c (print_ops): Take different args for indentation control.
+ (attr_callback): Caller updated.
+ Grok several more block-form attributes as being location expressions.
+ For those same attributes with udata forms, format output differently
+ for location list offset.
+ (print_debug_loc_section): Implement it for real.
+
+ * readelf.c (options): Mention ranges for --debug-dump.
+ (enum section_e): Add section_ranges.
+ (parse_opt): Grok "ranges" for -w/--debug-dump.
+ (print_debug_ranges_section): New function.
+ (print_debug): Handle .debug_ranges section.
+
+2005-05-30 Ulrich Drepper <drepper@redhat.com>
+
+ * readelf.c (handle_notes): At least x86-64 need not have the note
+ section values aligned to 8 bytes.
+
+2005-05-18 Ulrich Drepper <drepper@redhat.com>
+
+ * readelf.c (dwarf_tag_string): Add new tags.
+
2005-05-08 Roland McGrath <roland@redhat.com>
* strip.c (handle_elf): Don't translate hash and versym data formats,
diff --git a/elfutils/src/Makefile.am b/elfutils/src/Makefile.am
index 26b978cd..234d1b6f 100644
--- a/elfutils/src/Makefile.am
+++ b/elfutils/src/Makefile.am
@@ -15,19 +15,18 @@
DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H $(YYDEBUG) \
-DSRCDIR=\"$(shell cd $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\"
if MUDFLAP
-AM_CFLAGS = -Wall -Wshadow -Wunused -Wextra -std=gnu99 -fmudflap \
- $(native_ld_cflags) $(if $($(*F)_no_Wunused),,-Wunused) \
- $(if $($(*F)_no_Wformat),,-Wformat=2)
+AM_CFLAGS = -fmudflap
else
-AM_CFLAGS = -Wall -Wshadow -std=gnu99 $(native_ld_cflags) \
- $(if $($(*F)_no_Werror),,-Werror) \
- $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
- $(if $($(*F)_no_Wformat),,-Wformat=2)
+AM_CFLAGS =
endif
-if MUDFLAP
-libmudflap = -lmudflap
-endif
-INCLUDES = -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl -I$(srcdir)/../lib -I$(srcdir)/../libdw -I..
+AM_CFLAGS += -Wall -Wshadow -std=gnu99 $(native_ld_cflags) \
+ $(if $($(*F)_no_Werror),,-Werror) \
+ $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+ $(if $($(*F)_no_Wformat),,-Wformat=2)
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+ -I$(srcdir)/../libdw -I$(srcdir)/../libdwfl \
+ -I$(srcdir)/../lib -I..
YACC = @YACC@ -d
AM_YFLAGS = -pld
@@ -38,7 +37,8 @@ AM_LFLAGS = -Pld -olex.yy.c
native_ld = @native_ld@
base_cpu = @base_cpu@
-bin_PROGRAMS = readelf nm size strip ld elflint findtextrel addr2line
+bin_PROGRAMS = readelf nm size strip ld elflint findtextrel addr2line \
+ elfcmp objdump ranlib
ld_dsos = libld_elf_i386_pic.a
@@ -63,7 +63,11 @@ EXTRA_DIST = elf32-i386.script libld_elf_i386.map $(ld_modules)
ld_modules = i386_ld.c
if MUDFLAP
-libdw = ../libdw/libdw.a
+libmudflap = -lmudflap
+endif
+
+if BUILD_STATIC
+libdw = ../libdw/libdw.a $(libelf) $(libebl)
libelf = ../libelf/libelf.a
else
libdw = ../libdw/libdw.so
@@ -88,7 +92,10 @@ endif
ld_LDFLAGS = -rdynamic
elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
findtextrel_LDADD = $(libdw) $(libelf) $(libmudflap)
-addr2line_LDADD = $(libdw) $(libelf) $(libmudflap)
+addr2line_LDADD = $(libdw) $(libmudflap)
+elfcmp_LDADD = $(libebl) $(libelf) $(libmudflap) -ldl
+objdump_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+ranlib_LDADD = $(libelf) $(libeu) $(libmudflap)
ldlex.o: ldscript.c
ldlex_no_Werror = yes
diff --git a/elfutils/src/Makefile.in b/elfutils/src/Makefile.in
index d2114978..34e5eafd 100644
--- a/elfutils/src/Makefile.in
+++ b/elfutils/src/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,8 +16,6 @@
-SOURCES = $(libld_elf_a_SOURCES) $(libld_elf_i386_pic_a_SOURCES) addr2line.c elflint.c findtextrel.c $(ld_SOURCES) $(libld_elf_i386_so_SOURCES) nm.c readelf.c size.c strip.c
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -42,7 +40,8 @@ build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = readelf$(EXEEXT) nm$(EXEEXT) size$(EXEEXT) \
strip$(EXEEXT) ld$(EXEEXT) elflint$(EXEEXT) \
- findtextrel$(EXEEXT) addr2line$(EXEEXT)
+ findtextrel$(EXEEXT) addr2line$(EXEEXT) elfcmp$(EXEEXT) \
+ objdump$(EXEEXT) ranlib$(EXEEXT)
@NATIVE_LD_FALSE@noinst_PROGRAMS = $(am__EXEEXT_1)
@NATIVE_LD_TRUE@am__append_1 = libld_elf.a
subdir = src
@@ -72,52 +71,64 @@ am__EXEEXT_1 = libld_elf_i386.so$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
addr2line_SOURCES = addr2line.c
addr2line_OBJECTS = addr2line.$(OBJEXT)
-@MUDFLAP_FALSE@am__DEPENDENCIES_1 = ../libdw/libdw.so
-@MUDFLAP_TRUE@am__DEPENDENCIES_1 = ../libdw/libdw.a
-@MUDFLAP_FALSE@am__DEPENDENCIES_2 = ../libelf/libelf.so
-@MUDFLAP_TRUE@am__DEPENDENCIES_2 = ../libelf/libelf.a
-am__DEPENDENCIES_3 =
-addr2line_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+@BUILD_STATIC_FALSE@am__DEPENDENCIES_1 = ../libelf/libelf.so
+@BUILD_STATIC_TRUE@am__DEPENDENCIES_1 = ../libelf/libelf.a
+am__DEPENDENCIES_2 = ../libebl/libebl.a
+@BUILD_STATIC_FALSE@am__DEPENDENCIES_3 = ../libdw/libdw.so
+@BUILD_STATIC_TRUE@am__DEPENDENCIES_3 = ../libdw/libdw.a \
+@BUILD_STATIC_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+am__DEPENDENCIES_4 =
+addr2line_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_4)
+elfcmp_SOURCES = elfcmp.c
+elfcmp_OBJECTS = elfcmp.$(OBJEXT)
+elfcmp_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
elflint_SOURCES = elflint.c
elflint_OBJECTS = elflint.$(OBJEXT)
-am__DEPENDENCIES_4 = ../libebl/libebl.a
am__DEPENDENCIES_5 = ../lib/libeu.a
-elflint_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_3)
+elflint_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_4)
findtextrel_SOURCES = findtextrel.c
findtextrel_OBJECTS = findtextrel.$(OBJEXT)
-findtextrel_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+findtextrel_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
am_ld_OBJECTS = ld.$(OBJEXT) ldgeneric.$(OBJEXT) ldlex.$(OBJEXT) \
ldscript.$(OBJEXT) symbolhash.$(OBJEXT) sectionhash.$(OBJEXT) \
versionhash.$(OBJEXT)
ld_OBJECTS = $(am_ld_OBJECTS)
@NATIVE_LD_TRUE@am__DEPENDENCIES_6 = libld_elf.a
-ld_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_3) \
+ld_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_4) \
$(am__DEPENDENCIES_6)
am_libld_elf_i386_so_OBJECTS =
libld_elf_i386_so_OBJECTS = $(am_libld_elf_i386_so_OBJECTS)
libld_elf_i386_so_LDADD = $(LDADD)
nm_SOURCES = nm.c
nm_OBJECTS = nm.$(OBJEXT)
-nm_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_3)
+nm_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \
+ $(am__DEPENDENCIES_4)
+objdump_SOURCES = objdump.c
+objdump_OBJECTS = objdump.$(OBJEXT)
+objdump_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_4)
+ranlib_SOURCES = ranlib.c
+ranlib_OBJECTS = ranlib.$(OBJEXT)
+ranlib_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \
+ $(am__DEPENDENCIES_4)
readelf_SOURCES = readelf.c
readelf_OBJECTS = readelf.$(OBJEXT)
-readelf_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_3)
+readelf_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \
+ $(am__DEPENDENCIES_4)
size_SOURCES = size.c
size_OBJECTS = size.$(OBJEXT)
-size_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_3)
+size_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \
+ $(am__DEPENDENCIES_4)
strip_SOURCES = strip.c
strip_OBJECTS = strip.$(OBJEXT)
-strip_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_3)
+strip_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_4)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
@@ -128,11 +139,13 @@ LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
SOURCES = $(libld_elf_a_SOURCES) $(libld_elf_i386_pic_a_SOURCES) \
- addr2line.c elflint.c findtextrel.c $(ld_SOURCES) \
- $(libld_elf_i386_so_SOURCES) nm.c readelf.c size.c strip.c
+ addr2line.c elfcmp.c elflint.c findtextrel.c $(ld_SOURCES) \
+ $(libld_elf_i386_so_SOURCES) nm.c objdump.c ranlib.c readelf.c \
+ size.c strip.c
DIST_SOURCES = $(libld_elf_a_SOURCES) $(libld_elf_i386_pic_a_SOURCES) \
- addr2line.c elflint.c findtextrel.c $(ld_SOURCES) \
- $(libld_elf_i386_so_SOURCES) nm.c readelf.c size.c strip.c
+ addr2line.c elfcmp.c elflint.c findtextrel.c $(ld_SOURCES) \
+ $(libld_elf_i386_so_SOURCES) nm.c objdump.c ranlib.c readelf.c \
+ size.c strip.c
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
@@ -145,6 +158,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -160,6 +175,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -168,12 +185,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -235,17 +254,20 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Wshadow -std=gnu99 $(native_ld_cflags) \
-@MUDFLAP_FALSE@ $(if $($(*F)_no_Werror),,-Werror) \
-@MUDFLAP_FALSE@ $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
-@MUDFLAP_FALSE@ $(if $($(*F)_no_Wformat),,-Wformat=2)
-
-@MUDFLAP_TRUE@AM_CFLAGS = -Wall -Wshadow -Wunused -Wextra -std=gnu99 -fmudflap \
-@MUDFLAP_TRUE@ $(native_ld_cflags) $(if $($(*F)_no_Wunused),,-Wunused) \
-@MUDFLAP_TRUE@ $(if $($(*F)_no_Wformat),,-Wformat=2)
+@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Wshadow -std=gnu99 \
+@MUDFLAP_FALSE@ $(native_ld_cflags) $(if \
+@MUDFLAP_FALSE@ $($(*F)_no_Werror),,-Werror) $(if \
+@MUDFLAP_FALSE@ $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \
+@MUDFLAP_FALSE@ $($(*F)_no_Wformat),,-Wformat=2)
+@MUDFLAP_TRUE@AM_CFLAGS = -fmudflap -Wall -Wshadow -std=gnu99 \
+@MUDFLAP_TRUE@ $(native_ld_cflags) $(if \
+@MUDFLAP_TRUE@ $($(*F)_no_Werror),,-Werror) $(if \
+@MUDFLAP_TRUE@ $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \
+@MUDFLAP_TRUE@ $($(*F)_no_Wformat),,-Wformat=2)
+INCLUDES = -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+ -I$(srcdir)/../libdw -I$(srcdir)/../libdwfl \
+ -I$(srcdir)/../lib -I..
-@MUDFLAP_TRUE@libmudflap = -lmudflap
-INCLUDES = -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl -I$(srcdir)/../lib -I$(srcdir)/../libdw -I..
AM_YFLAGS = -pld
AM_LFLAGS = -Pld -olex.yy.c
native_ld = @native_ld@
@@ -262,10 +284,11 @@ noinst_HEADERS = ld.h symbolhash.h sectionhash.h versionhash.h \
EXTRA_DIST = elf32-i386.script libld_elf_i386.map $(ld_modules)
ld_modules = i386_ld.c
-@MUDFLAP_FALSE@libdw = ../libdw/libdw.so
-@MUDFLAP_TRUE@libdw = ../libdw/libdw.a
-@MUDFLAP_FALSE@libelf = ../libelf/libelf.so
-@MUDFLAP_TRUE@libelf = ../libelf/libelf.a
+@MUDFLAP_TRUE@libmudflap = -lmudflap
+@BUILD_STATIC_FALSE@libdw = ../libdw/libdw.so
+@BUILD_STATIC_TRUE@libdw = ../libdw/libdw.a $(libelf) $(libebl)
+@BUILD_STATIC_FALSE@libelf = ../libelf/libelf.so
+@BUILD_STATIC_TRUE@libelf = ../libelf/libelf.a
libebl = ../libebl/libebl.a
libeu = ../lib/libeu.a
nm_no_Wformat = yes
@@ -281,7 +304,10 @@ ld_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl \
ld_LDFLAGS = -rdynamic
elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
findtextrel_LDADD = $(libdw) $(libelf) $(libmudflap)
-addr2line_LDADD = $(libdw) $(libelf) $(libmudflap)
+addr2line_LDADD = $(libdw) $(libmudflap)
+elfcmp_LDADD = $(libebl) $(libelf) $(libmudflap) -ldl
+objdump_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+ranlib_LDADD = $(libelf) $(libeu) $(libmudflap)
ldlex_no_Werror = yes
# Machine-specific linker code.
@@ -363,6 +389,9 @@ clean-noinstPROGRAMS:
addr2line$(EXEEXT): $(addr2line_OBJECTS) $(addr2line_DEPENDENCIES)
@rm -f addr2line$(EXEEXT)
$(LINK) $(addr2line_LDFLAGS) $(addr2line_OBJECTS) $(addr2line_LDADD) $(LIBS)
+elfcmp$(EXEEXT): $(elfcmp_OBJECTS) $(elfcmp_DEPENDENCIES)
+ @rm -f elfcmp$(EXEEXT)
+ $(LINK) $(elfcmp_LDFLAGS) $(elfcmp_OBJECTS) $(elfcmp_LDADD) $(LIBS)
elflint$(EXEEXT): $(elflint_OBJECTS) $(elflint_DEPENDENCIES)
@rm -f elflint$(EXEEXT)
$(LINK) $(elflint_LDFLAGS) $(elflint_OBJECTS) $(elflint_LDADD) $(LIBS)
@@ -375,6 +404,12 @@ ld$(EXEEXT): $(ld_OBJECTS) $(ld_DEPENDENCIES)
nm$(EXEEXT): $(nm_OBJECTS) $(nm_DEPENDENCIES)
@rm -f nm$(EXEEXT)
$(LINK) $(nm_LDFLAGS) $(nm_OBJECTS) $(nm_LDADD) $(LIBS)
+objdump$(EXEEXT): $(objdump_OBJECTS) $(objdump_DEPENDENCIES)
+ @rm -f objdump$(EXEEXT)
+ $(LINK) $(objdump_LDFLAGS) $(objdump_OBJECTS) $(objdump_LDADD) $(LIBS)
+ranlib$(EXEEXT): $(ranlib_OBJECTS) $(ranlib_DEPENDENCIES)
+ @rm -f ranlib$(EXEEXT)
+ $(LINK) $(ranlib_LDFLAGS) $(ranlib_OBJECTS) $(ranlib_LDADD) $(LIBS)
readelf$(EXEEXT): $(readelf_OBJECTS) $(readelf_DEPENDENCIES)
@rm -f readelf$(EXEEXT)
$(LINK) $(readelf_LDFLAGS) $(readelf_OBJECTS) $(readelf_LDADD) $(LIBS)
@@ -393,6 +428,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/$(base_cpu)_ld.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addr2line.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfcmp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elflint.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findtextrel.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ld.Po@am__quote@
@@ -400,6 +436,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldscript.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objdump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ranlib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readelf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sectionhash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/size.Po@am__quote@
diff --git a/elfutils/src/addr2line.c b/elfutils/src/addr2line.c
index 60fcdf63..97eaed10 100644
--- a/elfutils/src/addr2line.c
+++ b/elfutils/src/addr2line.c
@@ -21,9 +21,9 @@
#include <errno.h>
#include <error.h>
#include <fcntl.h>
-#include <gelf.h>
#include <inttypes.h>
-#include <libdw.h>
+#include <libdwfl.h>
+#include <dwarf.h>
#include <libintl.h>
#include <locale.h>
#include <mcheck.h>
@@ -49,9 +49,6 @@ const char *argp_program_bug_address = PACKAGE_BUGREPORT;
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
{
- { NULL, 0, NULL, 0, N_("Input Selection:"), 0 },
- { "exe", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 },
-
{ NULL, 0, NULL, 0, N_("Output Selection:"), 0 },
{ "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 },
{ "functions", 'f', NULL, 0, N_("Additional show function names"), 0 },
@@ -74,19 +71,18 @@ static const char args_doc[] = N_("[ADDR...]");
/* Prototype for option handler. */
static error_t parse_opt (int key, char *arg, struct argp_state *state);
+static struct argp_child argp_children[2]; /* [0] is set in main. */
+
/* Data structure to communicate with argp functions. */
-static struct argp argp =
+static const struct argp argp =
{
- options, parse_opt, args_doc, doc, NULL, NULL, NULL
+ options, parse_opt, args_doc, doc, argp_children, NULL, NULL
};
/* Handle ADDR. */
-static void handle_address (GElf_Addr addr, Elf *elf, Dwarf *dw);
-
+static void handle_address (GElf_Addr addr, Dwfl *dwfl);
-/* Name of the executable. */
-static const char *executable = "a.out";
/* True if only base names of files should be shown. */
static bool only_basenames;
@@ -116,55 +112,11 @@ main (int argc, char *argv[])
/* Initialize the message catalog. */
(void) textdomain (PACKAGE);
- /* Parse and process arguments. */
- (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
-
- /* Tell the library which version we are expecting. */
- elf_version (EV_CURRENT);
-
- /* Open the file. */
- int fd = open64 (executable, O_RDONLY);
- if (fd == -1)
- error (1, errno, gettext ("cannot open '%s'"), executable);
-
- /* Create the ELF descriptor. */
- Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
- if (elf == NULL)
- {
- close (fd);
- error (1, 0, gettext ("cannot create ELF descriptor: %s"),
- elf_errmsg (-1));
- }
-
- /* Try to get a DWARF descriptor. If it fails, we try to locate the
- debuginfo file. */
- Dwarf *dw = dwarf_begin_elf (elf, DWARF_C_READ, NULL);
- int fd2 = -1;
- Elf *elf2 = NULL;
- if (dw == NULL)
- {
- char *canon = canonicalize_file_name (executable);
- GElf_Ehdr ehdr_mem;
- GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
-
- if (canon != NULL && ehdr != NULL)
- {
- const char *debuginfo_dir;
- if (ehdr->e_ident[EI_CLASS] == ELFCLASS32
- || ehdr->e_machine == EM_IA_64 || ehdr->e_machine == EM_ALPHA)
- debuginfo_dir = "/usr/lib/debug";
- else
- debuginfo_dir = "/usr/lib64/debug";
-
- char *difname = alloca (strlen (debuginfo_dir) + strlen (canon) + 1);
- strcpy (stpcpy (difname, debuginfo_dir), canon);
- fd2 = open64 (difname, O_RDONLY);
- if (fd2 != -1)
- dw = dwarf_begin_elf (elf2, DWARF_C_READ, NULL);
- }
-
- free (canon);
- }
+ /* Parse and process arguments. This includes opening the modules. */
+ argp_children[0].argp = dwfl_standard_argp ();
+ Dwfl *dwfl = NULL;
+ (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl);
+ assert (dwfl != NULL);
/* Now handle the addresses. In case none are given on the command
line, read from stdin. */
@@ -183,7 +135,7 @@ main (int argc, char *argv[])
char *endp;
uintmax_t addr = strtoumax (buf, &endp, 0);
if (endp != buf)
- handle_address (addr, elf2 ?: elf, dw);
+ handle_address (addr, dwfl);
else
result = 1;
}
@@ -197,7 +149,7 @@ main (int argc, char *argv[])
char *endp;
uintmax_t addr = strtoumax (argv[remaining], &endp, 0);
if (endp != argv[remaining])
- handle_address (addr, elf2 ?: elf, dw);
+ handle_address (addr, dwfl);
else
result = 1;
}
@@ -224,21 +176,21 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
/* Handle program arguments. */
static error_t
-parse_opt (int key, char *arg,
- struct argp_state *state __attribute__ ((unused)))
+parse_opt (int key, char *arg __attribute__ ((unused)),
+ struct argp_state *state)
{
switch (key)
{
+ case ARGP_KEY_INIT:
+ state->child_inputs[0] = state->input;
+ break;
+
case 'b':
case 'C':
case OPT_DEMANGLER:
/* Ignored for compatibility. */
break;
- case 'e':
- executable = arg;
- break;
-
case 's':
only_basenames = true;
break;
@@ -254,118 +206,108 @@ parse_opt (int key, char *arg,
}
-struct func_arg
-{
- GElf_Addr addr;
- const char *name;
-};
-
-
-static int
-match_func (Dwarf_Func *func, void *arg)
+static const char *
+dwarf_diename_integrate (Dwarf_Die *die)
{
- struct func_arg *func_arg = (struct func_arg *) arg;
- Dwarf_Addr addr;
-
- if (dwarf_func_lowpc (func, &addr) == 0 && addr <= func_arg->addr
- && dwarf_func_highpc (func, &addr) == 0 && func_arg->addr < addr)
- {
- func_arg->name = dwarf_func_name (func);
- return DWARF_CB_ABORT;
- }
-
- return DWARF_CB_OK;
+ Dwarf_Attribute attr_mem;
+ return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
}
-
-static const char *
-elf_getname (GElf_Addr addr, Elf *elf)
+static bool
+print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
{
- /* The DWARF information is not available. Use the ELF
- symbol table. */
- Elf_Scn *scn = NULL;
- Elf_Scn *dynscn = NULL;
-
- while ((scn = elf_nextscn (elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr != NULL)
+ Dwarf_Addr bias = 0;
+ Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias);
+
+ Dwarf_Die *scopes;
+ int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes);
+ if (nscopes <= 0)
+ return false;
+
+ for (int i = 0; i < nscopes; ++i)
+ switch (dwarf_tag (&scopes[i]))
+ {
+ case DW_TAG_subprogram:
{
- if (shdr->sh_type == SHT_SYMTAB)
- break;
- if (shdr->sh_type == SHT_DYNSYM)
- dynscn = scn;
+ const char *name = dwarf_diename_integrate (&scopes[i]);
+ if (name == NULL)
+ return false;
+ puts (name);
+ return true;
}
- }
- if (scn == NULL)
- scn = dynscn;
- if (scn != NULL)
- {
- /* Look through the symbol table for a matching symbol. */
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- assert (shdr != NULL);
-
- Elf_Data *data = elf_getdata (scn, NULL);
- if (data != NULL)
- for (int cnt = 1; cnt < (int) (shdr->sh_size / shdr->sh_entsize);
- ++cnt)
- {
- GElf_Sym sym_mem;
- GElf_Sym *sym = gelf_getsym (data, cnt, &sym_mem);
- if (sym != NULL
- && sym->st_value <= addr
- && addr < sym->st_value + sym->st_size)
- return elf_strptr (elf, shdr->sh_link, sym->st_name);
- }
- }
+ case DW_TAG_inlined_subroutine:
+ {
+ const char *name = dwarf_diename_integrate (&scopes[i]);
+ if (name == NULL)
+ return false;
+ printf ("%s inlined", name);
+
+ Dwarf_Files *files;
+ if (dwarf_getsrcfiles (cudie, &files, NULL) == 0)
+ {
+ Dwarf_Attribute attr_mem;
+ Dwarf_Word val;
+ if (dwarf_formudata (dwarf_attr (&scopes[i],
+ DW_AT_call_file,
+ &attr_mem), &val) == 0)
+ {
+ const char *file = dwarf_filesrc (files, val, NULL, NULL);
+ int lineno = 0, colno = 0;
+ if (dwarf_formudata (dwarf_attr (&scopes[i],
+ DW_AT_call_line,
+ &attr_mem), &val) == 0)
+ lineno = val;
+ if (dwarf_formudata (dwarf_attr (&scopes[i],
+ DW_AT_call_column,
+ &attr_mem), &val) == 0)
+ colno = val;
+ if (lineno == 0)
+ {
+ if (file != NULL)
+ printf (" from %s", file);
+ }
+ else if (colno == 0)
+ printf (" at %s:%u", file, lineno);
+ else
+ printf (" at %s:%u:%u", file, lineno, colno);
+ }
+ }
+ printf (" in ");
+ continue;
+ }
+ }
- return NULL;
+ return false;
}
-
static void
-handle_address (GElf_Addr addr, Elf *elf, Dwarf *dw)
+handle_address (GElf_Addr addr, Dwfl *dwfl)
{
- Dwarf_Die die_mem;
- Dwarf_Die *die = dwarf_addrdie (dw, addr, &die_mem);
+ Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr);
if (show_functions)
{
/* First determine the function name. Use the DWARF information if
possible. */
- struct func_arg arg;
- arg.addr = addr;
- arg.name = NULL;
-
- if (dwarf_getfuncs (die, match_func, &arg, 0) <= 0)
- arg.name = elf_getname (addr, elf);
-
- puts (arg.name ?: "??");
+ if (! print_dwarf_function (mod, addr))
+ puts (dwfl_module_addrname (mod, addr) ?: "??");
}
+ Dwfl_Line *line = dwfl_module_getsrc (mod, addr);
- Dwarf_Line *line;
const char *src;
- if ((line = dwarf_getsrc_die (die, addr)) != NULL
- && (src = dwarf_linesrc (line, NULL, NULL)) != NULL)
+ int lineno, linecol;
+ if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
+ NULL, NULL)) != NULL)
{
if (only_basenames)
src = basename (src);
- int lineno;
- if (dwarf_lineno (line, &lineno) != -1)
- {
- int linecol;
- if (dwarf_linecol (line, &linecol) != -1 && linecol != 0)
- printf ("%s:%d:%d\n", src, lineno, linecol);
- else
- printf ("%s:%d\n", src, lineno);
- }
+ if (linecol != 0)
+ printf ("%s:%d:%d\n", src, lineno, linecol);
else
- printf ("%s:0\n", src);
+ printf ("%s:%d\n", src, lineno);
}
else
puts ("??:0");
diff --git a/elfutils/src/elfcmp.c b/elfutils/src/elfcmp.c
new file mode 100644
index 00000000..1b34e6b7
--- /dev/null
+++ b/elfutils/src/elfcmp.c
@@ -0,0 +1,624 @@
+/* Compare relevant content of two ELF files.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../libelf/elf-knowledge.h"
+#include "../libebl/libeblP.h"
+
+
+/* Prototypes of local functions. */
+static Elf *open_file (const char *fname, int *fdp, Ebl **eblp);
+static bool search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx);
+static int regioncompare (const void *p1, const void *p2);
+
+
+/* Name and version of program. */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+/* Bug report address. */
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
+/* Values for the parameters which have no short form. */
+#define OPT_GAPS 0x100
+
+/* Definitions of arguments for argp functions. */
+static const struct argp_option options[] =
+{
+ { NULL, 0, NULL, 0, N_("Control options:"), 0 },
+ { "gaps", OPT_GAPS, "ACTION", 0, N_("Control treatment of gaps in loadable segments [ignore|match] (default: ignore)"), 0 },
+ { "quiet", 'q', NULL, 0, N_("Output nothing; yield exit status only"), 0 },
+
+ { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
+ { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program. */
+static const char doc[] = N_("\
+Compare relevant parts of two ELF files for equality.");
+
+/* Strings for arguments in help texts. */
+static const char args_doc[] = N_("FILE1 FILE2");
+
+/* Prototype for option handler. */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions. */
+static struct argp argp =
+{
+ options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* How to treat gaps in loadable segments. */
+static enum
+ {
+ gaps_ignore = 0,
+ gaps_match
+ }
+ gaps;
+
+/* Structure to hold information about used regions. */
+struct region
+{
+ GElf_Addr from;
+ GElf_Addr to;
+ struct region *next;
+};
+
+/* Nonzero if only exit status is wanted. */
+static bool quiet;
+
+
+int
+main (int argc, char *argv[])
+{
+ /* Set locale. */
+ (void) setlocale (LC_ALL, "");
+
+ /* Make sure the message catalog can be found. */
+ (void) bindtextdomain (PACKAGE, LOCALEDIR);
+
+ /* Initialize the message catalog. */
+ (void) textdomain (PACKAGE);
+
+ /* Parse and process arguments. */
+ int remaining;
+ (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+ /* We expect exactly two non-option parameters. */
+ if (remaining + 2 != argc)
+ {
+ fputs (gettext ("Invalid number of parameters.\n"), stderr);
+ argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name);
+ exit (1);
+ }
+
+ /* Comparing the files is done in two phases:
+ 1. compare all sections. Sections which are irrelevant (i.e., if
+ strip would remove them) are ignored. Some section types are
+ handled special.
+ 2. all parts of the loadable segments which are not parts of any
+ section is compared according to the rules of the --gaps option.
+ */
+ int result = 0;
+ elf_version (EV_CURRENT);
+
+ const char *const fname1 = argv[remaining];
+ int fd1;
+ Ebl *ebl1;
+ Elf *elf1 = open_file (fname1, &fd1, &ebl1);
+
+ const char *const fname2 = argv[remaining + 1];
+ int fd2;
+ Ebl *ebl2;
+ Elf *elf2 = open_file (fname2, &fd2, &ebl2);
+
+ GElf_Ehdr ehdr1_mem;
+ GElf_Ehdr *ehdr1 = gelf_getehdr (elf1, &ehdr1_mem);
+ if (ehdr1 == NULL)
+ error (EXIT_FAILURE, 0, gettext ("cannot get ELF header of \"%s\": %s"),
+ fname1, elf_errmsg (-1));
+ GElf_Ehdr ehdr2_mem;
+ GElf_Ehdr *ehdr2 = gelf_getehdr (elf2, &ehdr2_mem);
+ if (ehdr2 == NULL)
+ error (EXIT_FAILURE, 0, gettext ("cannot get ELF header of \"%s\": %s"),
+ fname2, elf_errmsg (-1));
+
+ /* Compare the ELF headers. */
+ if (memcmp (ehdr1->e_ident, ehdr2->e_ident, EI_NIDENT) != 0
+ || ehdr1->e_type != ehdr2->e_type
+ || ehdr1->e_machine != ehdr2->e_machine
+ || ehdr1->e_version != ehdr2->e_version
+ || ehdr1->e_entry != ehdr2->e_entry
+ || ehdr1->e_phoff != ehdr2->e_phoff
+ || ehdr1->e_flags != ehdr2->e_flags
+ || ehdr1->e_ehsize != ehdr2->e_ehsize
+ || ehdr1->e_phentsize != ehdr2->e_phentsize
+ || ehdr1->e_phnum != ehdr2->e_phnum
+ || ehdr1->e_shentsize != ehdr2->e_shentsize)
+ {
+ if (! quiet)
+ error (0, 0, gettext ("%s %s diff: ELF header"), fname1, fname2);
+ result = 1;
+ goto out;
+ }
+
+ /* Iterate over all sections. We expect the sections in the two
+ files to match exactly. */
+ Elf_Scn *scn1 = NULL;
+ Elf_Scn *scn2 = NULL;
+ struct region *regions = NULL;
+ size_t nregions = 0;
+ while (1)
+ {
+ GElf_Shdr shdr1_mem;
+ GElf_Shdr *shdr1;
+ const char *sname1 = NULL;
+ do
+ {
+ scn1 = elf_nextscn (elf1, scn1);
+ shdr1 = gelf_getshdr (scn1, &shdr1_mem);
+ if (shdr1 != NULL)
+ sname1 = elf_strptr (elf1, ehdr1->e_shstrndx, shdr1->sh_name);
+ }
+ while (scn1 != NULL
+ && ebl_section_strip_p (ebl1, ehdr1, shdr1, sname1, true, false));
+
+ GElf_Shdr shdr2_mem;
+ GElf_Shdr *shdr2;
+ const char *sname2 = NULL;
+ do
+ {
+ scn2 = elf_nextscn (elf2, scn2);
+ shdr2 = gelf_getshdr (scn2, &shdr2_mem);
+ if (shdr2 != NULL)
+ sname2 = elf_strptr (elf2, ehdr2->e_shstrndx, shdr2->sh_name);
+ }
+ while (scn2 != NULL
+ && ebl_section_strip_p (ebl2, ehdr2, shdr2, sname2, true, false));
+
+ if (scn1 == NULL || scn2 == NULL)
+ break;
+
+ if (gaps != gaps_ignore && (shdr1->sh_flags & SHF_ALLOC) != 0)
+ {
+ struct region *newp = (struct region *) alloca (sizeof (*newp));
+ newp->from = shdr1->sh_offset;
+ newp->to = shdr1->sh_offset + shdr1->sh_size;
+ newp->next = regions;
+ regions = newp;
+
+ ++nregions;
+ }
+
+ /* Compare the headers. We allow the name to be at a different
+ location. */
+ if (strcmp (sname1, sname2) != 0)
+ {
+ header_mismatch:
+ error (0, 0, gettext ("%s %s differ: section header"),
+ fname1, fname2);
+ result = 1;
+ goto out;
+ }
+
+ /* We ignore certain sections. */
+ if (strcmp (sname1, ".gnu_debuglink") == 0
+ || strcmp (sname1, ".gnu.prelink_undo") == 0)
+ continue;
+
+ if (shdr1->sh_type != shdr2->sh_type
+ // XXX Any flags which should be ignored?
+ || shdr1->sh_flags != shdr2->sh_flags
+ || shdr1->sh_addr != shdr2->sh_addr
+ || shdr1->sh_offset != shdr2->sh_offset
+ || shdr1->sh_size != shdr2->sh_size
+ || shdr1->sh_link != shdr2->sh_link
+ || shdr1->sh_info != shdr2->sh_info
+ || shdr1->sh_addralign != shdr2->sh_addralign
+ || shdr1->sh_entsize != shdr2->sh_entsize)
+ goto header_mismatch;
+
+ Elf_Data *data1 = elf_getdata (scn1, NULL);
+ if (data1 == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get content of section %zu in \"%s\": %s"),
+ elf_ndxscn (scn1), fname1, elf_errmsg (-1));
+
+ Elf_Data *data2 = elf_getdata (scn2, NULL);
+ if (data2 == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get content of section %zu in \"%s\": %s"),
+ elf_ndxscn (scn2), fname2, elf_errmsg (-1));
+
+ switch (shdr1->sh_type)
+ {
+ case SHT_DYNSYM:
+ case SHT_SYMTAB:
+ /* Iterate over the symbol table. We ignore the st_size
+ value of undefined symbols. */
+ for (int ndx = 0; ndx < (int) (shdr1->sh_size / shdr1->sh_entsize);
+ ++ndx)
+ {
+ GElf_Sym sym1_mem;
+ GElf_Sym *sym1 = gelf_getsym (data1, ndx, &sym1_mem);
+ if (sym1 == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get symbol in \"%s\": %s"),
+ fname1, elf_errmsg (-1));
+ GElf_Sym sym2_mem;
+ GElf_Sym *sym2 = gelf_getsym (data2, ndx, &sym2_mem);
+ if (sym2 == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get symbol in \"%s\": %s"),
+ fname2, elf_errmsg (-1));
+
+ const char *name1 = elf_strptr (elf1, shdr1->sh_link,
+ sym1->st_name);
+ const char *name2 = elf_strptr (elf2, shdr2->sh_link,
+ sym2->st_name);
+ if (strcmp (name1, name2) != 0
+ || sym1->st_value != sym2->st_value
+ || (sym1->st_size != sym2->st_size
+ && sym1->st_shndx != SHN_UNDEF)
+ || sym1->st_info != sym2->st_info
+ || sym1->st_other != sym2->st_other
+ || sym1->st_shndx != sym1->st_shndx)
+ {
+ // XXX Do we want to allow reordered symbol tables?
+ symtab_mismatch:
+ if (! quiet)
+ {
+ if (elf_ndxscn (scn1) == elf_ndxscn (scn2))
+ error (0, 0,
+ gettext ("%s %s differ: symbol table [%zu]"),
+ fname1, fname2, elf_ndxscn (scn1));
+ else
+ error (0, 0, gettext ("\
+%s %s differ: symbol table [%zu,%zu]"),
+ fname1, fname2, elf_ndxscn (scn1),
+ elf_ndxscn (scn2));
+ }
+ result = 1;
+ goto out;
+ }
+
+ if (sym1->st_shndx == SHN_UNDEF
+ && sym1->st_size != sym2->st_size)
+ {
+ /* The size of the symbol in the object defining it
+ might have changed. That is OK unless the symbol
+ is used in a copy relocation. Look over the
+ sections in both files and determine which
+ relocation section uses this symbol table
+ section. Then look through the relocations to
+ see whether any copy relocation references this
+ symbol. */
+ if (search_for_copy_reloc (ebl1, elf_ndxscn (scn1), ndx)
+ || search_for_copy_reloc (ebl2, elf_ndxscn (scn2), ndx))
+ goto symtab_mismatch;
+ }
+ }
+ break;
+
+ default:
+ /* Compare the section content byte for byte. */
+ assert (shdr1->sh_type == SHT_NOBITS
+ || (data1->d_buf != NULL || data1->d_size == 0));
+ assert (shdr2->sh_type == SHT_NOBITS
+ || (data2->d_buf != NULL || data1->d_size == 0));
+
+ if (data1->d_size != data2->d_size
+ || (shdr1->sh_type != SHT_NOBITS
+ && memcmp (data1->d_buf, data2->d_buf, data1->d_size) != 0))
+ {
+ if (! quiet)
+ {
+ if (elf_ndxscn (scn1) == elf_ndxscn (scn2))
+ error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' content"),
+ fname1, fname2, elf_ndxscn (scn1), sname1);
+ else
+ if (elf_ndxscn (scn1) == elf_ndxscn (scn2))
+ error (0, 0, gettext ("\
+%s %s differ: section [%zu,%zu] '%s' content"),
+ fname1, fname2, elf_ndxscn (scn1),
+ elf_ndxscn (scn2), sname1);
+ }
+ result = 1;
+ goto out;
+ }
+ break;
+ }
+ }
+
+ if (scn1 != scn2)
+ {
+ if (! quiet)
+ error (0, 0,
+ gettext ("%s %s differ: unequal amount of important sections"),
+ fname1, fname2);
+ result = 1;
+ goto out;
+ }
+
+ /* We we look at gaps, create artificial ones for the parts of the
+ program which we are not in sections. */
+ struct region ehdr_region;
+ struct region phdr_region;
+ if (gaps != gaps_ignore)
+ {
+ ehdr_region.from = 0;
+ ehdr_region.to = ehdr1->e_ehsize;
+ ehdr_region.next = &phdr_region;
+
+ phdr_region.from = ehdr1->e_phoff;
+ phdr_region.to = ehdr1->e_phoff + ehdr1->e_phnum * ehdr1->e_phentsize;
+ phdr_region.next = regions;
+
+ regions = &ehdr_region;
+ nregions += 2;
+ }
+
+ /* If we need to look at the gaps we need access to the file data. */
+ char *raw1 = NULL;
+ size_t size1 = 0;
+ char *raw2 = NULL;
+ size_t size2 = 0;
+ struct region *regionsarr = alloca (nregions * sizeof (struct region));
+ if (gaps != gaps_ignore)
+ {
+ raw1 = elf_rawfile (elf1, &size1);
+ if (raw1 == NULL )
+ error (EXIT_FAILURE, 0, gettext ("cannot load data of \"%s\": %s"),
+ fname1, elf_errmsg (-1));
+
+ raw2 = elf_rawfile (elf2, &size2);
+ if (raw2 == NULL )
+ error (EXIT_FAILURE, 0, gettext ("cannot load data of \"%s\": %s"),
+ fname2, elf_errmsg (-1));
+
+ for (size_t cnt = 0; cnt < nregions; ++cnt)
+ {
+ regionsarr[cnt] = *regions;
+ regions = regions->next;
+ }
+
+ qsort (regionsarr, nregions, sizeof (regionsarr[0]), regioncompare);
+ }
+
+ /* Compare the program header tables. */
+ for (int ndx = 0; ndx < ehdr1->e_phnum; ++ndx)
+ {
+ GElf_Phdr phdr1_mem;
+ GElf_Phdr *phdr1 = gelf_getphdr (elf1, ndx, &phdr1_mem);
+ if (ehdr1 == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get program header entry %d of \"%s\": %s"),
+ ndx, fname1, elf_errmsg (-1));
+ GElf_Phdr phdr2_mem;
+ GElf_Phdr *phdr2 = gelf_getphdr (elf2, ndx, &phdr2_mem);
+ if (ehdr2 == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get program header entry %d of \"%s\": %s"),
+ ndx, fname2, elf_errmsg (-1));
+
+ if (memcmp (phdr1, phdr2, sizeof (GElf_Phdr)) != 0)
+ {
+ if (! quiet)
+ error (0, 0, gettext ("%s %s differ: program header %d"),
+ fname1, fname2, ndx);
+ result = 1;
+ goto out;
+ }
+
+ if (gaps != gaps_ignore && phdr1->p_type == PT_LOAD)
+ {
+ size_t cnt = 0;
+ while (cnt < nregions && regionsarr[cnt].to < phdr1->p_offset)
+ ++cnt;
+
+ GElf_Off last = phdr1->p_offset;
+ GElf_Off end = phdr1->p_offset + phdr1->p_filesz;
+ while (cnt < nregions && regionsarr[cnt].from < end)
+ {
+ if (last < regionsarr[cnt].from)
+ {
+ /* Compare the [LAST,FROM) region. */
+ assert (gaps == gaps_match);
+ if (memcmp (raw1 + last, raw2 + last,
+ regionsarr[cnt].from - last) != 0)
+ {
+ gapmismatch:
+ if (!quiet)
+ error (0, 0, gettext ("%s %s differ: gap"),
+ fname1, fname2);
+ result = 1;
+ goto out;
+ }
+
+ }
+ last = regionsarr[cnt].to;
+ ++cnt;
+ }
+
+ if (cnt == nregions && last < end)
+ goto gapmismatch;
+ }
+ }
+
+ out:
+ elf_end (elf1);
+ elf_end (elf2);
+ close (fd1);
+ close (fd2);
+
+ return result;
+}
+
+
+/* Print the version information. */
+static void
+print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
+{
+ fprintf (stream, "elfcmp (%s) %s\n", PACKAGE_NAME, VERSION);
+ fprintf (stream, gettext ("\
+Copyright (C) %s Red Hat, Inc.\n\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "2005");
+ fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
+}
+
+
+/* Handle program arguments. */
+static error_t
+parse_opt (int key, char *arg,
+ struct argp_state *state __attribute__ ((unused)))
+{
+ switch (key)
+ {
+ case 'q':
+ quiet = true;
+ break;
+
+ case OPT_GAPS:
+ if (strcasecmp (arg, "ignore") == 0)
+ gaps = gaps_ignore;
+ else if (strcasecmp (arg, "match") == 0)
+ gaps = gaps_match;
+ else
+ {
+ fprintf (stderr,
+ gettext ("Invalid value \"%s\" for --gaps parameter."),
+ arg);
+ argp_help (&argp, stderr, ARGP_HELP_SEE,
+ program_invocation_short_name);
+ exit (1);
+ }
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+
+static Elf *
+open_file (const char *fname, int *fdp, Ebl **eblp)
+{
+ int fd = open (fname, O_RDONLY);
+ if (unlikely (fd == -1))
+ error (EXIT_FAILURE, errno, gettext ("cannot open \"%s\""), fname);
+ Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+ if (elf == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot create ELF descriptor for \"%s\": %s"),
+ fname, elf_errmsg (-1));
+ Ebl *ebl = ebl_openbackend (elf);
+ if (ebl == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot create EBL descriptor for \"%s\""), fname);
+
+ *fdp = fd;
+ *eblp = ebl;
+ return elf;
+}
+
+
+static bool
+search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx)
+{
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header of section %zu: %s"),
+ elf_ndxscn (scn), elf_errmsg (-1));
+
+ if ((shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA)
+ || shdr->sh_link != scnndx)
+ continue;
+
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get content of section %zu: %s"),
+ elf_ndxscn (scn), elf_errmsg (-1));
+
+ if (shdr->sh_type == SHT_REL)
+ for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize);
+ ++ndx)
+ {
+ GElf_Rel rel_mem;
+ GElf_Rel *rel = gelf_getrel (data, ndx, &rel_mem);
+ if (rel == NULL)
+ error (EXIT_FAILURE, 0, gettext ("cannot get relocation: %s"),
+ elf_errmsg (-1));
+
+ if ((int) GELF_R_SYM (rel->r_info) == symndx
+ && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info)))
+ return true;
+ }
+ else
+ for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize);
+ ++ndx)
+ {
+ GElf_Rela rela_mem;
+ GElf_Rela *rela = gelf_getrela (data, ndx, &rela_mem);
+ if (rela == NULL)
+ error (EXIT_FAILURE, 0, gettext ("cannot get relocation: %s"),
+ elf_errmsg (-1));
+
+ if ((int) GELF_R_SYM (rela->r_info) == symndx
+ && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+static int
+regioncompare (const void *p1, const void *p2)
+{
+ const struct region *r1 = (const struct region *) p1;
+ const struct region *r2 = (const struct region *) p2;
+
+ if (r1->from < r2->from)
+ return -1;
+ return 1;
+}
diff --git a/elfutils/src/elflint.c b/elfutils/src/elflint.c
index 31043335..d91ac0f8 100644
--- a/elfutils/src/elflint.c
+++ b/elfutils/src/elflint.c
@@ -24,7 +24,6 @@
#include <fcntl.h>
#include <gelf.h>
#include <inttypes.h>
-#include <libebl.h>
#include <libintl.h>
#include <locale.h>
#include <stdbool.h>
@@ -35,6 +34,7 @@
#include <elf-knowledge.h>
#include <system.h>
+#include "../libebl/libeblP.h"
/* Name and version of program. */
@@ -289,7 +289,7 @@ process_file (int fd, Elf *elf, const char *prefix, const char *suffix,
default:
/* We cannot do anything. */
ERROR (gettext ("\
-Not an ELF file - it has the wrong magic bytes at the start"));
+Not an ELF file - it has the wrong magic bytes at the start\n"));
break;
}
}
@@ -420,9 +420,7 @@ executables and DSOs cannot have zero program header offset\n"));
/* Get the header of the zeroth section. The sh_size field
might contain the section number. */
GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
-
- shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+ GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
if (shdr != NULL)
{
/* The error will be reported later. */
@@ -439,17 +437,9 @@ invalid number of section header table entries\n"));
/* Get the header of the zeroth section. The sh_size field
might contain the section number. */
GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
-
- shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
- if (shdr != NULL)
- {
- /* The error will be reported later. */
- if (shdr->sh_link >= shnum)
- ERROR (gettext ("invalid section header index\n"));
- else
- shstrndx = shdr->sh_link;
- }
+ GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+ if (shdr != NULL && shdr->sh_link < shnum)
+ shstrndx = shdr->sh_link;
}
else if (shstrndx >= shnum)
ERROR (gettext ("invalid section header index\n"));
@@ -511,15 +501,9 @@ check_scn_group (Ebl *ebl, int idx)
for (cnt = idx + 1; cnt < shnum; ++cnt)
{
- Elf_Scn *scn;
+ Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
- Elf_Data *data;
- Elf32_Word *grpdata;
- size_t inner;
-
- scn = elf_getscn (ebl->elf, cnt);
- shdr = gelf_getshdr (scn, &shdr_mem);
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
if (shdr == NULL)
/* We cannot get the section header so we cannot check it.
The error to get the section header will be shown
@@ -529,13 +513,14 @@ check_scn_group (Ebl *ebl, int idx)
if (shdr->sh_type != SHT_GROUP)
continue;
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL || data->d_size < sizeof (Elf32_Word))
/* Cannot check the section. */
continue;
- grpdata = (Elf32_Word *) data->d_buf;
- for (inner = 1; inner < data->d_size / sizeof (Elf32_Word); ++inner)
+ Elf32_Word *grpdata = (Elf32_Word *) data->d_buf;
+ for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word);
+ ++inner)
if (grpdata[inner] == (Elf32_Word) idx)
goto out;
}
@@ -555,20 +540,11 @@ section [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"),
static void
-check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
+check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
bool no_xndx_warned = false;
int no_pt_tls = 0;
-
- Elf_Scn *scn = elf_getscn (ebl->elf, idx);
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- GElf_Shdr strshdr_mem;
- GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &strshdr_mem);
- if (shdr == NULL || strshdr == NULL)
- return;
- Elf_Data *data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
if (data == NULL)
{
ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
@@ -576,6 +552,12 @@ check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
return;
}
+ GElf_Shdr strshdr_mem;
+ GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &strshdr_mem);
+ if (strshdr == NULL)
+ return;
+
if (strshdr->sh_type != SHT_STRTAB)
ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
shdr->sh_link, section_name (ebl, shdr->sh_link),
@@ -583,30 +565,31 @@ check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
/* Search for an extended section index table section. */
size_t cnt;
- GElf_Shdr xndxshdr_mem;
- GElf_Shdr *xndxshdr = NULL;
Elf_Data *xndxdata = NULL;
Elf32_Word xndxscnidx = 0;
+ bool found_xndx = false;
for (cnt = 1; cnt < shnum; ++cnt)
if (cnt != (size_t) idx)
{
Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt);
- xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
- xndxdata = elf_getdata (xndxscn, NULL);
- xndxscnidx = elf_ndxscn (xndxscn);
-
- if (xndxshdr == NULL || xndxdata == NULL)
+ GElf_Shdr xndxshdr_mem;
+ GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
+ if (xndxshdr == NULL)
continue;
if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX
&& xndxshdr->sh_link == (GElf_Word) idx)
- break;
+ {
+ if (found_xndx)
+ ERROR (gettext ("\
+section [%2d] '%s': symbol table cannot have more than one extended index section\n"),
+ idx, section_name (ebl, idx));
+
+ xndxdata = elf_getdata (xndxscn, NULL);
+ xndxscnidx = elf_ndxscn (xndxscn);
+ found_xndx = true;
+ }
}
- if (cnt == shnum)
- {
- xndxshdr = NULL;
- xndxdata = NULL;
- }
if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT))
ERROR (gettext ("\
@@ -695,7 +678,8 @@ section [%2d] '%s': symbol %zu: invalid section index\n"),
else
xndx = sym->st_shndx;
- if (GELF_ST_TYPE (sym->st_info) >= STT_NUM)
+ if (GELF_ST_TYPE (sym->st_info) >= STT_NUM
+ && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0))
ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"),
idx, section_name (ebl, idx), cnt);
@@ -730,16 +714,21 @@ section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"),
{
if (GELF_ST_TYPE (sym->st_info) != STT_TLS)
{
- if ((sym->st_value - destshdr->sh_addr) > destshdr->sh_size)
- ERROR (gettext ("\
+ if (! ebl_check_special_symbol (ebl, ehdr, sym, name,
+ destshdr))
+ {
+ if ((sym->st_value - destshdr->sh_addr)
+ > destshdr->sh_size)
+ ERROR (gettext ("\
section [%2d] '%s': symbol %zu: st_value out of bounds\n"),
- idx, section_name (ebl, idx), cnt);
- else if ((sym->st_value - destshdr->sh_addr + sym->st_size)
- > destshdr->sh_size)
- ERROR (gettext ("\
+ idx, section_name (ebl, idx), cnt);
+ else if ((sym->st_value - destshdr->sh_addr
+ + sym->st_size) > destshdr->sh_size)
+ ERROR (gettext ("\
section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
- idx, section_name (ebl, idx), cnt,
- (int) xndx, section_name (ebl, xndx));
+ idx, section_name (ebl, idx), cnt,
+ (int) xndx, section_name (ebl, xndx));
+ }
}
else
{
@@ -838,59 +827,77 @@ section [%2d] '%s': symbol %zu: non-local section symbol\n"),
{
if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
{
- /* Check that address and size match the global offset
- table. We have to locate the GOT by searching for a
- section named ".got". */
- Elf_Scn *gscn = NULL;
- GElf_Addr addr = 0;
- GElf_Xword size = 0;
- bool found = false;
-
- while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL)
- {
- GElf_Shdr gshdr_mem;
- GElf_Shdr *gshdr = gelf_getshdr (gscn, &gshdr_mem);
- assert (gshdr != NULL);
+ /* Check that address and size match the global offset table. */
+
+ GElf_Shdr destshdr_mem;
+ GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx),
+ &destshdr_mem);
- const char *sname = elf_strptr (ebl->elf, ehdr->e_shstrndx,
- gshdr->sh_name);
- if (sname != NULL)
+ if (destshdr == NULL && xndx == SHN_ABS)
+ {
+ /* In a DSO, we have to find the GOT section by name. */
+ Elf_Scn *gotscn = NULL;
+ Elf_Scn *gscn = NULL;
+ while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL)
{
- if (strcmp (sname, ".got.plt") == 0)
- {
- addr = gshdr->sh_addr;
- size = gshdr->sh_size;
- found = true;
- break;
- }
- if (strcmp (sname, ".got") == 0)
+ destshdr = gelf_getshdr (gscn, &destshdr_mem);
+ assert (destshdr != NULL);
+ const char *sname = elf_strptr (ebl->elf,
+ ehdr->e_shstrndx,
+ destshdr->sh_name);
+ if (sname != NULL)
{
- addr = gshdr->sh_addr;
- size = gshdr->sh_size;
- found = true;
- /* Do not stop looking. There might be a
- .got.plt section. */
+ if (strcmp (sname, ".got.plt") == 0)
+ break;
+ if (strcmp (sname, ".got") == 0)
+ /* Do not stop looking.
+ There might be a .got.plt section. */
+ gotscn = gscn;
}
+
+ destshdr = NULL;
}
+
+ if (destshdr == NULL && gotscn != NULL)
+ destshdr = gelf_getshdr (gotscn, &destshdr_mem);
}
- if (found)
+ const char *sname = (destshdr == NULL ? NULL
+ : elf_strptr (ebl->elf, ehdr->e_shstrndx,
+ destshdr->sh_name));
+ if (sname == NULL)
+ ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section\n"),
+ idx, section_name (ebl, idx));
+ else if (strcmp (sname, ".got.plt") != 0
+ && strcmp (sname, ".got") != 0)
+ ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to '%s' section\n"),
+ idx, section_name (ebl, idx), sname);
+
+ if (destshdr != NULL)
{
/* Found it. */
- if (sym->st_value != addr)
- /* This test is more strict than the psABIs which
- usually allow the symbol to be in the middle of
- the .got section, allowing negative offsets. */
- ERROR (gettext ("\
-section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match .got section address %#" PRIx64 "\n"),
- idx, section_name (ebl, idx),
- (uint64_t) sym->st_value, (uint64_t) addr);
+ if (!ebl_check_special_symbol (ebl, ehdr, sym, name,
+ destshdr))
+ {
+ if (sym->st_value != destshdr->sh_addr)
+ /* This test is more strict than the psABIs which
+ usually allow the symbol to be in the middle of
+ the .got section, allowing negative offsets. */
+ ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"),
+ idx, section_name (ebl, idx),
+ (uint64_t) sym->st_value,
+ sname, (uint64_t) destshdr->sh_addr);
- if (!gnuld && sym->st_size != size)
- ERROR (gettext ("\
-section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match .got section size %" PRIu64 "\n"),
- idx, section_name (ebl, idx),
- (uint64_t) sym->st_size, (uint64_t) size);
+ if (!gnuld && sym->st_size != destshdr->sh_size)
+ ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"),
+ idx, section_name (ebl, idx),
+ (uint64_t) sym->st_size,
+ sname, (uint64_t) destshdr->sh_size);
+ }
}
else
ERROR (gettext ("\
@@ -898,36 +905,32 @@ section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"
idx, section_name (ebl, idx));
}
else if (strcmp (name, "_DYNAMIC") == 0)
- {
- /* Check that address and size match the dynamic
- section. We locate the dynamic section via the
- program header entry. */
- int pcnt;
-
- for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt)
- {
- GElf_Phdr phdr_mem;
- GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
+ /* Check that address and size match the dynamic section.
+ We locate the dynamic section via the program header
+ entry. */
+ for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt)
+ {
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
- if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
- {
- if (sym->st_value != phdr->p_vaddr)
- ERROR (gettext ("\
+ if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
+ {
+ if (sym->st_value != phdr->p_vaddr)
+ ERROR (gettext ("\
section [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"),
- idx, section_name (ebl, idx),
- (uint64_t) sym->st_value,
- (uint64_t) phdr->p_vaddr);
+ idx, section_name (ebl, idx),
+ (uint64_t) sym->st_value,
+ (uint64_t) phdr->p_vaddr);
- if (!gnuld && sym->st_size != phdr->p_memsz)
- ERROR (gettext ("\
+ if (!gnuld && sym->st_size != phdr->p_memsz)
+ ERROR (gettext ("\
section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"),
- idx, section_name (ebl, idx),
- (uint64_t) sym->st_size,
- (uint64_t) phdr->p_memsz);
+ idx, section_name (ebl, idx),
+ (uint64_t) sym->st_size,
+ (uint64_t) phdr->p_memsz);
- break;
- }
- }
+ break;
+ }
}
}
}
@@ -935,7 +938,8 @@ section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segm
static bool
-is_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, int idx, GElf_Shdr *shdr, bool rela)
+is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
+ bool rela)
{
/* If this is no executable or DSO it cannot be a .rel.dyn section. */
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
@@ -987,43 +991,41 @@ section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
}
-static void
-check_rela (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
+struct loaded_segment
{
- Elf_Scn *scn;
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
- Elf_Data *data;
- GElf_Shdr destshdr_mem;
- GElf_Shdr *destshdr = NULL;
- size_t cnt;
- bool reldyn = false;
- bool known_broken = gnuld;
+ GElf_Addr from;
+ GElf_Addr to;
+ bool read_only;
+ struct loaded_segment *next;
+};
- scn = elf_getscn (ebl->elf, idx);
- shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- return;
- data = elf_getdata (scn, NULL);
- if (data == NULL)
- {
- ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
- idx, section_name (ebl, idx));
- return;
- }
+
+/* Check whether binary has text relocation flag set. */
+static bool textrel;
+
+/* Keep track of whether text relocation flag is needed. */
+static bool needed_textrel;
+
+
+static bool
+check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
+ int idx, int reltype, GElf_Shdr **destshdrp,
+ GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp)
+{
+ bool reldyn = false;
/* Check whether the link to the section we relocate is reasonable. */
if (shdr->sh_info >= shnum)
ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"),
idx, section_name (ebl, idx));
- else
+ else if (shdr->sh_info != 0)
{
- destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
- &destshdr_mem);
- if (destshdr != NULL)
+ *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
+ destshdr_memp);
+ if (*destshdrp != NULL)
{
- if(destshdr->sh_type != SHT_PROGBITS
- && destshdr->sh_type != SHT_NOBITS)
+ if((*destshdrp)->sh_type != SHT_PROGBITS
+ && (*destshdrp)->sh_type != SHT_NOBITS)
{
reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true);
if (!reldyn)
@@ -1032,7 +1034,7 @@ section [%2d] '%s': invalid destination section type\n"),
idx, section_name (ebl, idx));
else
{
- /* There is no standard, but we require that .rela.dyn
+ /* There is no standard, but we require that .rel{,a}.dyn
sections have a sh_info value of zero. */
if (shdr->sh_info != 0)
ERROR (gettext ("\
@@ -1041,105 +1043,201 @@ section [%2d] '%s': sh_info should be zero\n"),
}
}
- if ((destshdr->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0)
+ if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0)
ERROR (gettext ("\
section [%2d] '%s': no relocations for merge-able sections possible\n"),
idx, section_name (ebl, idx));
}
}
- if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT))
- ERROR (gettext ("\
-section [%2d] '%s': section entry size does not match ElfXX_Rela\n"),
+ if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT))
+ ERROR (gettext (reltype == ELF_T_RELA ? "\
+section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
+section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
idx, section_name (ebl, idx));
- Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
- GElf_Shdr symshdr_mem;
- GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
- Elf_Data *symdata = elf_getdata (symscn, NULL);
-
- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+ /* In preparation of checking whether relocations are text
+ relocations or not we need to determine whether the file is
+ flagged to have text relocation and we need to determine a) what
+ the loaded segments are and b) which are read-only. This will
+ also allow us to determine whether the same reloc section is
+ modifying loaded and not loaded segments. */
+ for (int i = 0; i < ehdr->e_phnum; ++i)
{
- GElf_Rela rela_mem;
- GElf_Rela *rela;
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
+ if (phdr == NULL)
+ continue;
- rela = gelf_getrela (data, cnt, &rela_mem);
- if (rela == NULL)
+ if (phdr->p_type == PT_LOAD)
{
- ERROR (gettext ("\
-section [%2d] '%s': cannot get relocation %zu: %s\n"),
- idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
- continue;
+ struct loaded_segment *newp = xmalloc (sizeof (*newp));
+ newp->from = phdr->p_vaddr;
+ newp->to = phdr->p_vaddr + phdr->p_memsz;
+ newp->read_only = (phdr->p_flags & PF_W) == 0;
+ newp->next = *loadedp;
+ *loadedp = newp;
}
+ else if (phdr->p_type == PT_DYNAMIC)
+ {
+ Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset);
+ GElf_Shdr dynshdr_mem;
+ GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem);
+ Elf_Data *dyndata = elf_getdata (dynscn, NULL);
+ if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC
+ && dyndata != NULL)
+ for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j)
+ {
+ GElf_Dyn dyn_mem;
+ GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem);
+ if (dyn != NULL
+ && (dyn->d_tag == DT_TEXTREL
+ || (dyn->d_tag == DT_FLAGS
+ && (dyn->d_un.d_val & DF_TEXTREL) != 0)))
+ {
+ textrel = true;
+ break;
+ }
+ }
+ }
+ }
- if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rela->r_info)))
- ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
- idx, section_name (ebl, idx), cnt);
- else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rela->r_info)))
+ /* A quick test which can be easily done here (although it is a bit
+ out of place): the text relocation flag makes only sense if there
+ is a segment which is not writable. */
+ if (textrel)
+ {
+ struct loaded_segment *seg = *loadedp;
+ while (seg != NULL && !seg->read_only)
+ seg = seg->next;
+ if (seg == NULL)
ERROR (gettext ("\
+text relocation flag set but there is no read-only segment\n"));
+ }
+
+ return reldyn;
+}
+
+
+enum load_state
+ {
+ state_undecided,
+ state_loaded,
+ state_unloaded,
+ state_error
+ };
+
+
+static void
+check_one_reloc (Ebl *ebl, int idx, size_t cnt, const GElf_Shdr *symshdr,
+ Elf_Data *symdata, GElf_Addr r_offset, GElf_Xword r_info,
+ const GElf_Shdr *destshdr, bool reldyn,
+ struct loaded_segment *loaded, enum load_state *statep)
+{
+ bool known_broken = gnuld;
+
+ if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info)))
+ ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
+ idx, section_name (ebl, idx), cnt);
+ else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info)))
+ ERROR (gettext ("\
section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
- idx, section_name (ebl, idx), cnt);
+ idx, section_name (ebl, idx), cnt);
- if (symshdr != NULL
- && ((GELF_R_SYM (rela->r_info) + 1)
- * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)
- > symshdr->sh_size))
- ERROR (gettext ("\
+ if (symshdr != NULL
+ && ((GELF_R_SYM (r_info) + 1)
+ * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)
+ > symshdr->sh_size))
+ ERROR (gettext ("\
section [%2d] '%s': relocation %zu: invalid symbol index\n"),
- idx, section_name (ebl, idx), cnt);
+ idx, section_name (ebl, idx), cnt);
- if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rela->r_info)))
- {
- const char *name;
- char buf[64];
- GElf_Sym sym_mem;
- GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rela->r_info),
- &sym_mem);
- if (sym != NULL
- /* Get the name for the symbol. */
- && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
- && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 )
- ERROR (gettext ("\
+ if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info)))
+ {
+ const char *name;
+ char buf[64];
+ GElf_Sym sym_mem;
+ GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
+ if (sym != NULL
+ /* Get the name for the symbol. */
+ && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
+ && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 )
+ ERROR (gettext ("\
section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"),
- idx, section_name (ebl, idx), cnt,
- ebl_reloc_type_name (ebl, GELF_R_SYM (rela->r_info),
- buf, sizeof (buf)));
- }
+ idx, section_name (ebl, idx), cnt,
+ ebl_reloc_type_name (ebl, GELF_R_SYM (r_info),
+ buf, sizeof (buf)));
+ }
- if (reldyn)
- {
- // XXX TODO Check .rel.dyn section addresses.
- }
- else if (!known_broken)
- {
- if (destshdr != NULL
- && (rela->r_offset - destshdr->sh_addr) >= destshdr->sh_size)
- ERROR (gettext ("\
+ if (reldyn)
+ {
+ // XXX TODO Check .rel.dyn section addresses.
+ }
+ else if (!known_broken)
+ {
+ if (destshdr != NULL
+ && GELF_R_TYPE (r_info) != 0
+ && (r_offset - destshdr->sh_addr) >= destshdr->sh_size)
+ ERROR (gettext ("\
section [%2d] '%s': relocation %zu: offset out of bounds\n"),
idx, section_name (ebl, idx), cnt);
+ }
+
+ GElf_Sym sym_mem;
+ GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
+
+ if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info))
+ /* Make sure the referenced symbol is an object or unspecified. */
+ && sym != NULL
+ && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE
+ && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
+ {
+ char buf[64];
+ ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"),
+ idx, section_name (ebl, idx), cnt,
+ ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
+ buf, sizeof (buf)));
+ }
+
+ bool in_loaded_seg = false;
+ while (loaded != NULL)
+ {
+ if (r_offset < loaded->to
+ && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from)
+ {
+ /* The symbol is in this segment. */
+ if (loaded->read_only)
+ {
+ if (textrel)
+ needed_textrel = true;
+ else
+ ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"),
+ idx, section_name (ebl, idx), cnt);
+ }
+
+ in_loaded_seg = true;
}
+
+ loaded = loaded->next;
+ }
+
+ if (*statep == state_undecided)
+ *statep = in_loaded_seg ? state_loaded : state_unloaded;
+ else if ((*statep == state_unloaded && in_loaded_seg)
+ || (*statep == state_loaded && !in_loaded_seg))
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': relocations are against loaded and unloaded data\n"),
+ idx, section_name (ebl, idx));
+ *statep = state_error;
}
}
static void
-check_rel (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
+check_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
- Elf_Scn *scn;
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
- Elf_Data *data;
- GElf_Shdr destshdr_mem;
- GElf_Shdr *destshdr = NULL;
- size_t cnt;
- bool reldyn = false;
- bool known_broken = gnuld;
-
- scn = elf_getscn (ebl->elf, idx);
- shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- return;
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
if (data == NULL)
{
ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
@@ -1147,58 +1245,72 @@ check_rel (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
return;
}
- /* Check whether the link to the section we relocate is reasonable. */
- if (shdr->sh_info >= shnum)
- ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"),
- idx, section_name (ebl, idx));
- else
+ /* Check the fields of the section header. */
+ GElf_Shdr destshdr_mem;
+ GElf_Shdr *destshdr = NULL;
+ struct loaded_segment *loaded = NULL;
+ bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr,
+ &destshdr_mem, &loaded);
+
+ Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+ GElf_Shdr symshdr_mem;
+ GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+ Elf_Data *symdata = elf_getdata (symscn, NULL);
+ enum load_state state = state_undecided;
+
+ for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
{
- destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
- &destshdr_mem);
- if (destshdr != NULL)
+ GElf_Rela rela_mem;
+ GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
+ if (rela == NULL)
{
- if (destshdr->sh_type != SHT_PROGBITS
- && destshdr->sh_type != SHT_NOBITS)
- {
- reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, false);
- if (!reldyn)
- ERROR (gettext ("\
-section [%2d] '%s': invalid destination section type\n"),
- idx, section_name (ebl, idx));
- else
- {
- /* There is no standard, but we require that .rela.dyn
- sections have a sh_info value of zero. */
- if (shdr->sh_info != 0)
- ERROR (gettext ("\
-section [%2d] '%s': sh_info should be zero\n"),
- idx, section_name (ebl, idx));
- }
- }
-
- if ((destshdr->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0)
- ERROR (gettext ("\
-section [%2d] '%s': no relocations for merge-able sections possible\n"),
- idx, section_name (ebl, idx));
+ ERROR (gettext ("\
+section [%2d] '%s': cannot get relocation %zu: %s\n"),
+ idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
+ continue;
}
+
+ check_one_reloc (ebl, idx, cnt, symshdr, symdata, rela->r_offset,
+ rela->r_info, destshdr, reldyn, loaded, &state);
}
- if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT))
- ERROR (gettext ("\
-section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
- idx, section_name (ebl, idx));
+ while (loaded != NULL)
+ {
+ struct loaded_segment *old = loaded;
+ loaded = loaded->next;
+ free (old);
+ }
+}
+
+
+static void
+check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+ if (data == NULL)
+ {
+ ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+ idx, section_name (ebl, idx));
+ return;
+ }
+
+ /* Check the fields of the section header. */
+ GElf_Shdr destshdr_mem;
+ GElf_Shdr *destshdr = NULL;
+ struct loaded_segment *loaded = NULL;
+ bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr,
+ &destshdr_mem, &loaded);
Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
GElf_Shdr symshdr_mem;
GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
Elf_Data *symdata = elf_getdata (symscn, NULL);
+ enum load_state state = state_undecided;
- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+ for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
{
GElf_Rel rel_mem;
- GElf_Rel *rel;
-
- rel = gelf_getrel (data, cnt, &rel_mem);
+ GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
if (rel == NULL)
{
ERROR (gettext ("\
@@ -1207,53 +1319,15 @@ section [%2d] '%s': cannot get relocation %zu: %s\n"),
continue;
}
- if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)))
- ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
- idx, section_name (ebl, idx), cnt);
- else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rel->r_info)))
- ERROR (gettext ("\
-section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
- idx, section_name (ebl, idx), cnt);
-
- if (symshdr != NULL
- && ((GELF_R_SYM (rel->r_info) + 1)
- * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)
- > symshdr->sh_size))
- ERROR (gettext ("\
-section [%2d] '%s': relocation %zu: invalid symbol index\n"),
- idx, section_name (ebl, idx), cnt);
-
- if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rel->r_info)))
- {
- const char *name;
- char buf[64];
- GElf_Sym sym_mem;
- GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rel->r_info),
- &sym_mem);
- if (sym != NULL
- /* Get the name for the symbol. */
- && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
- && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 )
- ERROR (gettext ("\
-section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"),
- idx, section_name (ebl, idx), cnt,
- ebl_reloc_type_name (ebl, GELF_R_SYM (rel->r_info),
- buf, sizeof (buf)));
- }
+ check_one_reloc (ebl, idx, cnt, symshdr, symdata, rel->r_offset,
+ rel->r_info, destshdr, reldyn, loaded, &state);
+ }
- if (reldyn)
- {
- // XXX TODO Check .rel.dyn section addresses.
- }
- else if (!known_broken)
- {
- if (destshdr != NULL
- && GELF_R_TYPE (rel->r_info) != 0
- && (rel->r_offset - destshdr->sh_addr) >= destshdr->sh_size)
- ERROR (gettext ("\
-section [%2d] '%s': relocation %zu: offset out of bounds\n"),
- idx, section_name (ebl, idx), cnt);
- }
+ while (loaded != NULL)
+ {
+ struct loaded_segment *old = loaded;
+ loaded = loaded->next;
+ free (old);
}
}
@@ -1263,11 +1337,8 @@ static int ndynamic;
static void
-check_dynamic (Ebl *ebl, int idx)
+check_dynamic (Ebl *ebl, GElf_Shdr *shdr, int idx)
{
- Elf_Scn *scn;
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
Elf_Data *data;
GElf_Shdr strshdr_mem;
GElf_Shdr *strshdr;
@@ -1322,11 +1393,7 @@ check_dynamic (Ebl *ebl, int idx)
if (++ndynamic == 2)
ERROR (gettext ("more than one dynamic section present\n"));
- scn = elf_getscn (ebl->elf, idx);
- shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- return;
- data = elf_getdata (scn, NULL);
+ data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
if (data == NULL)
{
ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
@@ -1354,9 +1421,7 @@ section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
{
GElf_Dyn dyn_mem;
- GElf_Dyn *dyn;
-
- dyn = gelf_getdyn (data, cnt, &dyn_mem);
+ GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
if (dyn == NULL)
{
ERROR (gettext ("\
@@ -1377,7 +1442,7 @@ section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"),
ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"),
idx, section_name (ebl, idx), cnt);
- if (dyn->d_tag < DT_NUM)
+ if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM)
{
if (has_dt[dyn->d_tag]
&& dyn->d_tag != DT_NEEDED
@@ -1424,9 +1489,7 @@ section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"),
for (cnt = 1; cnt < DT_NUM; ++cnt)
if (has_dt[cnt])
{
- int inner;
-
- for (inner = 0; inner < DT_NUM; ++inner)
+ for (int inner = 0; inner < DT_NUM; ++inner)
if (dependencies[cnt][inner] && ! has_dt[inner])
{
char buf1[50];
@@ -1469,30 +1532,24 @@ section [%2d] '%s': not all of %s, %s, and %s are present\n"),
static void
-check_symtab_shndx (Ebl *ebl, int idx)
+check_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
- Elf_Scn *scn;
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
- GElf_Shdr symshdr_mem;
- GElf_Shdr *symshdr;
- Elf_Scn *symscn;
- size_t cnt;
- Elf_Data *data;
- Elf_Data *symdata;
-
- scn = elf_getscn (ebl->elf, idx);
- shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- return;
+ if (ehdr->e_type != ET_REL)
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': only relocatable files can have extended section index\n"),
+ idx, section_name (ebl, idx));
+ return;
+ }
- symscn = elf_getscn (ebl->elf, shdr->sh_link);
- symshdr = gelf_getshdr (symscn, &symshdr_mem);
+ Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+ GElf_Shdr symshdr_mem;
+ GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB)
ERROR (gettext ("\
section [%2d] '%s': extended section index section not for symbol table\n"),
idx, section_name (ebl, idx));
- symdata = elf_getdata (symscn, NULL);
+ Elf_Data *symdata = elf_getdata (symscn, NULL);
if (symdata == NULL)
ERROR (gettext ("cannot get data for symbol section\n"));
@@ -1512,12 +1569,10 @@ section [%2d] '%s': extended index table too small for symbol table\n"),
ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
idx, section_name (ebl, idx));
- for (cnt = idx + 1; cnt < shnum; ++cnt)
+ for (size_t cnt = idx + 1; cnt < shnum; ++cnt)
{
GElf_Shdr rshdr_mem;
- GElf_Shdr *rshdr;
-
- rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem);
+ GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem);
if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX
&& rshdr->sh_link == shdr->sh_link)
{
@@ -1529,12 +1584,12 @@ section [%2d] '%s': extended section index in section [%2zu] '%s' refers to same
}
}
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
if (*((Elf32_Word *) data->d_buf) != 0)
ERROR (gettext ("symbol 0 should have zero extended section index\n"));
- for (cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
+ for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
{
Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt];
@@ -1558,22 +1613,17 @@ extended section index is %" PRIu32 " but symbol index is not XINDEX\n"),
static void
-check_hash (Ebl *ebl, int idx)
+check_hash (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
- Elf_Scn *scn;
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
- Elf_Data *data;
- Elf32_Word nbucket;
- Elf32_Word nchain;
- GElf_Shdr symshdr_mem;
- GElf_Shdr *symshdr;
+ if (ehdr->e_type == ET_REL)
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': relocatable files cannot have hash tables\n"),
+ idx, section_name (ebl, idx));
+ return;
+ }
- scn = elf_getscn (ebl->elf, idx);
- shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- return;
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
if (data == NULL)
{
ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
@@ -1581,7 +1631,9 @@ check_hash (Ebl *ebl, int idx)
return;
}
- symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &symshdr_mem);
+ GElf_Shdr symshdr_mem;
+ GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &symshdr_mem);
if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM)
ERROR (gettext ("\
section [%2d] '%s': hash table not for dynamic symbol table\n"),
@@ -1604,8 +1656,8 @@ section [%2d] '%s': hash table has not even room for nbucket and nchain\n"),
return;
}
- nbucket = ((Elf32_Word *) data->d_buf)[0];
- nchain = ((Elf32_Word *) data->d_buf)[1];
+ Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
+ Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize)
ERROR (gettext ("\
@@ -1753,10 +1805,8 @@ section [%2d] '%s': section index %Zu out of range\n"),
else
{
GElf_Shdr refshdr_mem;
- GElf_Shdr *refshdr;
-
- refshdr = gelf_getshdr (elf_getscn (ebl->elf, val),
- &refshdr_mem);
+ GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val),
+ &refshdr_mem);
if (refshdr == NULL)
ERROR (gettext ("\
section [%2d] '%s': cannot get section header for element %zu: %s\n"),
@@ -1787,56 +1837,6 @@ section [%2d] '%s' is contained in more than one section group\n"),
}
-static bool has_loadable_segment;
-static bool has_interp_segment;
-
-static const struct
-{
- const char *name;
- size_t namelen;
- GElf_Word type;
- enum { unused, exact, atleast } attrflag;
- GElf_Word attr;
- GElf_Word attr2;
-} special_sections[] =
- {
- /* See figure 4-14 in the gABI. */
- { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
- { ".comment", 8, SHT_PROGBITS, exact, 0, 0 },
- { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
- { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
- { ".debug", 7, SHT_PROGBITS, exact, 0, 0 },
- { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE },
- { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 },
- { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 },
- { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
- { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
- { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info?
- { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 },
- { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
- { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
- { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests?
- { ".line", 6, SHT_PROGBITS, exact, 0, 0 },
- { ".note", 6, SHT_NOTE, exact, 0, 0 },
- { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests
- { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
- { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests
- { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests
- { ".rodata", 8, SHT_PROGBITS, exact, SHF_ALLOC, 0 },
- { ".rodata1", 9, SHT_PROGBITS, exact, SHF_ALLOC, 0 },
- { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 },
- { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
- { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
- { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests
- { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
- { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
- { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
- { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }
- };
-#define nspecial_sections \
- (sizeof (special_sections) / sizeof (special_sections[0]))
-
-
static const char *
section_flags_string (GElf_Word flags, char *buf, size_t len)
{
@@ -1862,9 +1862,8 @@ section_flags_string (GElf_Word flags, char *buf, size_t len)
const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]);
char *cp = buf;
- size_t cnt;
- for (cnt = 0; cnt < nknown_flags; ++cnt)
+ for (size_t cnt = 0; cnt < nknown_flags; ++cnt)
if (flags & known_flags[cnt].flag)
{
if (cp != buf && len > 1)
@@ -1889,14 +1888,126 @@ section_flags_string (GElf_Word flags, char *buf, size_t len)
}
+static int
+has_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx)
+{
+ /* First find the relocation section for the symbol table. */
+ Elf_Scn *scn = NULL;
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = NULL;
+ while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+ {
+ shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr != NULL
+ && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+ && shdr->sh_link == symscnndx)
+ /* Found the section. */
+ break;
+ }
+
+ if (scn == NULL)
+ return 0;
+
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data == NULL)
+ return 0;
+
+ if (shdr->sh_type == SHT_REL)
+ for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
+ {
+ GElf_Rel rel_mem;
+ GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
+ if (rel == NULL)
+ continue;
+
+ if (GELF_R_SYM (rel->r_info) == symndx
+ && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info)))
+ return 1;
+ }
+ else
+ for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
+ {
+ GElf_Rela rela_mem;
+ GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
+ if (rela == NULL)
+ continue;
+
+ if (GELF_R_SYM (rela->r_info) == symndx
+ && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info)))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int
+in_nobits_scn (Ebl *ebl, unsigned int shndx)
+{
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem);
+ return shdr != NULL && shdr->sh_type == SHT_NOBITS;
+}
+
+
+static struct version_namelist
+{
+ const char *objname;
+ const char *name;
+ GElf_Word ndx;
+ enum { ver_def, ver_need } type;
+ struct version_namelist *next;
+} *version_namelist;
+
+
+static int
+add_version (const char *objname, const char *name, GElf_Word ndx, int type)
+{
+ /* Check that there are no duplications. */
+ struct version_namelist *nlp = version_namelist;
+ while (nlp != NULL)
+ {
+ if (((nlp->objname == NULL && objname == NULL)
+ || (nlp->objname != NULL && objname != NULL
+ && strcmp (nlp->objname, objname) == 0))
+ && strcmp (nlp->name, name) == 0)
+ return nlp->type == ver_def ? 1 : -1;
+ nlp = nlp->next;
+ }
+
+ nlp = xmalloc (sizeof (*nlp));
+ nlp->objname = objname;
+ nlp->name = name;
+ nlp->ndx = ndx;
+ nlp->type = type;
+ nlp->next = version_namelist;
+ version_namelist = nlp;
+
+ return 0;
+}
+
+
static void
-check_versym (Ebl *ebl, GElf_Shdr *shdr, int idx)
+check_versym (Ebl *ebl, int idx)
{
- /* The number of elements in the version symbol table must be the
- same as the number of symbols. */
+ Elf_Scn *scn = elf_getscn (ebl->elf, idx);
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr == NULL)
+ /* The error has already been reported. */
+ return;
+
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data == NULL)
+ {
+ ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+ idx, section_name (ebl, idx));
+ return;
+ }
+
+ Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
GElf_Shdr symshdr_mem;
- GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &symshdr_mem);
+ GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
if (symshdr == NULL)
/* The error has already been reported. */
return;
@@ -1910,6 +2021,8 @@ section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic s
return;
}
+ /* The number of elements in the version symbol table must be the
+ same as the number of symbols. */
if (shdr->sh_size / shdr->sh_entsize
!= symshdr->sh_size / symshdr->sh_entsize)
ERROR (gettext ("\
@@ -1917,21 +2030,485 @@ section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\
idx, section_name (ebl, idx),
shdr->sh_link, section_name (ebl, shdr->sh_link));
- // XXX TODO A lot more tests
- // check value of the fields. local symbols must have zero entries.
- // nonlocal symbols refer to valid version. Check that version index
- // in bound.
+ Elf_Data *symdata = elf_getdata (symscn, NULL);
+ if (symdata == NULL)
+ /* The error has already been reported. */
+ return;
+
+ for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+ {
+ GElf_Versym versym_mem;
+ GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem);
+ if (versym == NULL)
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': symbol %d: cannot read version data\n"),
+ idx, section_name (ebl, idx), cnt);
+ break;
+ }
+
+ GElf_Sym sym_mem;
+ GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem);
+ if (sym == NULL)
+ /* Already reported elsewhere. */
+ continue;
+
+ if (*versym == VER_NDX_GLOBAL)
+ {
+ /* Global symbol. Make sure it is not defined as local. */
+ if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
+ ERROR (gettext ("\
+section [%2d] '%s': symbol %d: local symbol with global scope\n"),
+ idx, section_name (ebl, idx), cnt);
+ }
+ else if (*versym != VER_NDX_LOCAL)
+ {
+ /* Versioned symbol. Make sure it is not defined as local. */
+ if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL)
+ ERROR (gettext ("\
+section [%2d] '%s': symbol %d: local symbol with version\n"),
+ idx, section_name (ebl, idx), cnt);
+
+ /* Look through the list of defined versions and locate the
+ index we need for this symbol. */
+ struct version_namelist *runp = version_namelist;
+ while (runp != NULL)
+ if (runp->ndx == *versym)
+ break;
+ else
+ runp = runp->next;
+
+ if (runp == NULL)
+ ERROR (gettext ("\
+section [%2d] '%s': symbol %d: invalid version index %d\n"),
+ idx, section_name (ebl, idx), cnt, (int) *versym);
+ else if (sym->st_shndx == SHN_UNDEF
+ && runp->type == ver_def)
+ ERROR (gettext ("\
+section [%2d] '%s': symbol %d: version index %d is for defined version\n"),
+ idx, section_name (ebl, idx), cnt, (int) *versym);
+ else if (sym->st_shndx != SHN_UNDEF
+ && runp->type == ver_need)
+ {
+ /* Unless this symbol has a copy relocation associated
+ this must not happen. */
+ if (!has_copy_reloc (ebl, shdr->sh_link, cnt)
+ && !in_nobits_scn (ebl, sym->st_shndx))
+ ERROR (gettext ("\
+section [%2d] '%s': symbol %d: version index %d is for requested version\n"),
+ idx, section_name (ebl, idx), cnt, (int) *versym);
+ }
+ }
+ }
}
-static void
-check_sections (Ebl *ebl, GElf_Ehdr *ehdr)
+static int
+unknown_dependency_p (Elf *elf, GElf_Ehdr *ehdr, const char *fname)
{
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = NULL;
+
+ int i;
+ for (i = 0; i < ehdr->e_phnum; ++i)
+ if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL
+ && phdr->p_type == PT_DYNAMIC)
+ break;
+
+ if (i == ehdr->e_phnum)
+ return 1;
+ assert (phdr != NULL);
+ Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
GElf_Shdr shdr_mem;
- GElf_Shdr *shdr;
- size_t cnt;
- bool dot_interp_section = false;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL)
+ for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
+ {
+ GElf_Dyn dyn_mem;
+ GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
+ if (dyn != NULL && dyn->d_tag == DT_NEEDED)
+ {
+ const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
+ if (str != NULL && strcmp (str, fname) == 0)
+ /* Found it. */
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+
+static unsigned int nverneed;
+
+static void
+check_verneed (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+ if (++nverneed == 2)
+ ERROR (gettext ("more than one version reference section present\n"));
+ GElf_Shdr strshdr_mem;
+ GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &strshdr_mem);
+ if (strshdr == NULL)
+ return;
+ if (strshdr->sh_type != SHT_STRTAB)
+ ERROR (gettext ("\
+section [%2d] '%s': sh_link does not link to string table\n"),
+ idx, section_name (ebl, idx));
+
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+ if (data == NULL)
+ {
+ ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+ idx, section_name (ebl, idx));
+ return;
+ }
+ unsigned int offset = 0;
+ for (int cnt = shdr->sh_info; --cnt >= 0; )
+ {
+ /* Get the data at the next offset. */
+ GElf_Verneed needmem;
+ GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
+ if (need == NULL)
+ break;
+
+ unsigned int auxoffset = offset + need->vn_aux;
+
+ if (need->vn_version != EV_CURRENT)
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong version %d\n"),
+ idx, section_name (ebl, idx), cnt, (int) need->vn_version);
+
+ if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED,
+ 1, EV_CURRENT))
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
+ idx, section_name (ebl, idx), cnt);
+
+ const char *libname = elf_strptr (ebl->elf, shdr->sh_link,
+ need->vn_file);
+ if (libname == NULL)
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid file reference\n"),
+ idx, section_name (ebl, idx), cnt);
+ goto next_need;
+ }
+
+ /* Check that there is a DT_NEEDED entry for the referenced library. */
+ if (unknown_dependency_p (ebl->elf, ehdr, libname))
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d references unknown dependency\n"),
+ idx, section_name (ebl, idx), cnt);
+
+ for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
+ {
+ GElf_Vernaux auxmem;
+ GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
+ if (aux == NULL)
+ break;
+
+ if ((aux->vna_flags & ~VER_FLG_WEAK) != 0)
+ ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"),
+ idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+
+ const char *verstr = elf_strptr (ebl->elf, shdr->sh_link,
+ aux->vna_name);
+ if (verstr == NULL)
+ ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"),
+ idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+ else
+ {
+ GElf_Word hashval = elf_hash (verstr);
+ if (hashval != aux->vna_hash)
+ ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"),
+ idx, section_name (ebl, idx), need->vn_cnt - cnt2,
+ cnt, (int) hashval, (int) aux->vna_hash);
+
+ int res = add_version (libname, verstr, aux->vna_other,
+ ver_need);
+ if (unlikely (res !=0))
+ {
+ assert (res > 0);
+ ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"),
+ idx, section_name (ebl, idx), need->vn_cnt - cnt2,
+ cnt, verstr);
+ }
+ }
+
+ if ((aux->vna_next != 0 || cnt2 > 0)
+ && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1,
+ EV_CURRENT))
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"),
+ idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+ break;
+ }
+
+ auxoffset += MAX (aux->vna_next,
+ gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT));
+ }
+
+ /* Find the next offset. */
+ next_need:
+ offset += need->vn_next;
+
+ if ((need->vn_next != 0 || cnt > 0)
+ && offset < auxoffset)
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid offset to next entry\n"),
+ idx, section_name (ebl, idx), cnt);
+ }
+}
+
+
+static unsigned int nverdef;
+
+static void
+check_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx)
+{
+ if (++nverdef == 2)
+ ERROR (gettext ("more than one version definition section present\n"));
+
+ GElf_Shdr strshdr_mem;
+ GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &strshdr_mem);
+ if (strshdr == NULL)
+ return;
+ if (strshdr->sh_type != SHT_STRTAB)
+ ERROR (gettext ("\
+section [%2d] '%s': sh_link does not link to string table\n"),
+ idx, section_name (ebl, idx));
+
+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+ if (data == NULL)
+ {
+ no_data:
+ ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+ idx, section_name (ebl, idx));
+ return;
+ }
+
+ /* Iterate over all version definition entries. We check that there
+ is a BASE entry and that each index is unique. To do the later
+ we collection the information in a list which is later
+ examined. */
+ struct namelist
+ {
+ const char *name;
+ struct namelist *next;
+ } *namelist = NULL;
+ struct namelist *refnamelist = NULL;
+
+ bool has_base = false;
+ unsigned int offset = 0;
+ for (int cnt = shdr->sh_info; --cnt >= 0; )
+ {
+ /* Get the data at the next offset. */
+ GElf_Verdef defmem;
+ GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
+ if (def == NULL)
+ goto no_data;
+
+ if ((def->vd_flags & VER_FLG_BASE) != 0)
+ {
+ if (has_base)
+ ERROR (gettext ("\
+section [%2d] '%s': more than one BASE definition\n"),
+ idx, section_name (ebl, idx));
+ if (def->vd_ndx != VER_NDX_GLOBAL)
+ ERROR (gettext ("\
+section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"),
+ idx, section_name (ebl, idx));
+ has_base = true;
+ }
+ if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0)
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has unknown flag\n"),
+ idx, section_name (ebl, idx), cnt);
+
+ if (def->vd_version != EV_CURRENT)
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong version %d\n"),
+ idx, section_name (ebl, idx), cnt, (int) def->vd_version);
+
+ if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF,
+ 1, EV_CURRENT))
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
+ idx, section_name (ebl, idx), cnt);
+
+ unsigned int auxoffset = offset + def->vd_aux;
+ GElf_Verdaux auxmem;
+ GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
+ if (aux == NULL)
+ goto no_data;
+
+ const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
+ if (name == NULL)
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid name reference\n"),
+ idx, section_name (ebl, idx), cnt);
+ goto next_def;
+ }
+ GElf_Word hashval = elf_hash (name);
+ if (def->vd_hash != hashval)
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"),
+ idx, section_name (ebl, idx), cnt, (int) hashval,
+ (int) def->vd_hash);
+
+ int res = add_version (NULL, name, def->vd_ndx, ver_def);
+ if (unlikely (res !=0))
+ {
+ assert (res > 0);
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has duplicate version name '%s'\n"),
+ idx, section_name (ebl, idx), cnt, name);
+ }
+
+ struct namelist *newname = alloca (sizeof (*newname));
+ newname->name = name;
+ newname->next = namelist;
+ namelist = newname;
+
+ auxoffset += aux->vda_next;
+ for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
+ {
+ aux = gelf_getverdaux (data, auxoffset, &auxmem);
+ if (aux == NULL)
+ goto no_data;
+
+ name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
+ if (name == NULL)
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"),
+ idx, section_name (ebl, idx), cnt);
+ else
+ {
+ newname = alloca (sizeof (*newname));
+ newname->name = name;
+ newname->next = refnamelist;
+ refnamelist = newname;
+ }
+
+ if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt)
+ && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1,
+ EV_CURRENT))
+ {
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"),
+ idx, section_name (ebl, idx), cnt);
+ break;
+ }
+
+ auxoffset += MAX (aux->vda_next,
+ gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT));
+ }
+
+ /* Find the next offset. */
+ next_def:
+ offset += def->vd_next;
+
+ if ((def->vd_next != 0 || cnt > 0)
+ && offset < auxoffset)
+ ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid offset to next entry\n"),
+ idx, section_name (ebl, idx), cnt);
+ }
+
+ if (!has_base)
+ ERROR (gettext ("section [%2d] '%s': no BASE definition\n"),
+ idx, section_name (ebl, idx));
+
+ /* Check whether the referenced names are available. */
+ while (namelist != NULL)
+ {
+ struct version_namelist *runp = version_namelist;
+ while (runp != NULL)
+ {
+ if (runp->type == ver_def
+ && strcmp (runp->name, namelist->name) == 0)
+ break;
+ runp = runp->next;
+ }
+
+ if (runp == NULL)
+ ERROR (gettext ("\
+section [%2d] '%s': unknown parent version '%s'\n"),
+ idx, section_name (ebl, idx), namelist->name);
+
+ namelist = namelist->next;
+ }
+}
+
+
+static bool has_loadable_segment;
+static bool has_interp_segment;
+
+static const struct
+{
+ const char *name;
+ size_t namelen;
+ GElf_Word type;
+ enum { unused, exact, atleast } attrflag;
+ GElf_Word attr;
+ GElf_Word attr2;
+} special_sections[] =
+ {
+ /* See figure 4-14 in the gABI. */
+ { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
+ { ".comment", 8, SHT_PROGBITS, exact, 0, 0 },
+ { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
+ { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
+ { ".debug", 7, SHT_PROGBITS, exact, 0, 0 },
+ { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE },
+ { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 },
+ { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 },
+ { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
+ { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
+ { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info?
+ { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 },
+ { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
+ { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
+ { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests?
+ { ".line", 6, SHT_PROGBITS, exact, 0, 0 },
+ { ".note", 6, SHT_NOTE, exact, 0, 0 },
+ { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests
+ { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
+ { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests
+ { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests
+ { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
+ { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
+ { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 },
+ { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
+ { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
+ { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests
+ { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
+ { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
+ { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
+ { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
+
+ /* The following are GNU extensions. */
+ { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 },
+ { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 },
+ { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 }
+ };
+#define nspecial_sections \
+ (sizeof (special_sections) / sizeof (special_sections[0]))
+
+
+static void
+check_sections (Ebl *ebl, GElf_Ehdr *ehdr)
+{
if (ehdr->e_shoff == 0)
/* No section header. */
return;
@@ -1942,7 +2519,8 @@ check_sections (Ebl *ebl, GElf_Ehdr *ehdr)
/* Check the zeroth section first. It must not have any contents
and the section header must contain nonzero value at most in the
sh_size and sh_link fields. */
- shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
if (shdr == NULL)
ERROR (gettext ("cannot get section header of zeroth section\n"));
else
@@ -1973,12 +2551,12 @@ zeroth section has nonzero size value while ELF header has nonzero shnum value\n
zeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n"));
}
- for (cnt = 1; cnt < shnum; ++cnt)
- {
- Elf_Scn *scn;
+ bool dot_interp_section = false;
- scn = elf_getscn (ebl->elf, cnt);
- shdr = gelf_getshdr (scn, &shdr_mem);
+ size_t versym_scnndx = 0;
+ for (size_t cnt = 1; cnt < shnum; ++cnt)
+ {
+ shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem);
if (shdr == NULL)
{
ERROR (gettext ("\
@@ -2004,7 +2582,13 @@ cannot get section header for section [%2zu] '%s': %s\n"),
char stbuf2[100];
char stbuf3[100];
- if (shdr->sh_type != special_sections[s].type
+ GElf_Word good_type = special_sections[s].type;
+ if (special_sections[s].namelen == sizeof ".plt" &&
+ !memcmp (special_sections[s].name, ".plt", sizeof ".plt")
+ && ebl_bss_plt_p (ebl, ehdr))
+ good_type = SHT_NOBITS;
+
+ if (shdr->sh_type != good_type
&& !(is_debuginfo && shdr->sh_type == SHT_NOBITS))
ERROR (gettext ("\
section [%2d] '%s' has wrong type: expected %s, is %s\n"),
@@ -2121,16 +2705,20 @@ section [%2zu] '%s': size not multiple of entry size\n"),
&& shdr->sh_type != SHT_CHECKSUM
&& shdr->sh_type != SHT_GNU_verdef
&& shdr->sh_type != SHT_GNU_verneed
- && shdr->sh_type != SHT_GNU_versym)
- ERROR (gettext ("unsupported section type %d\n"), (int) shdr->sh_type);
+ && shdr->sh_type != SHT_GNU_versym
+ && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL)
+ ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"),
+ cnt, section_name (ebl, cnt),
+ (int) shdr->sh_type);
#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \
| SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \
| SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS)
if (shdr->sh_flags & ~ALL_SH_FLAGS)
- ERROR (gettext ("section [%2zu] '%s' contain unknown flag(s) %d\n"),
+ ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)"
+ " %#" PRIx64 "\n"),
cnt, section_name (ebl, cnt),
- (int) shdr->sh_flags & ~ALL_SH_FLAGS);
+ (uint64_t) shdr->sh_flags & ~(uint64_t) ALL_SH_FLAGS);
else if (shdr->sh_flags & SHF_TLS)
{
// XXX Correct?
@@ -2201,7 +2789,9 @@ section [%2zu] '%s' has type NOBITS but is read from the file in segment of prog
}
else
{
- if (shdr->sh_offset >= phdr->p_offset + phdr->p_filesz)
+ const GElf_Off end = phdr->p_offset + phdr->p_filesz;
+ if (shdr->sh_offset > end ||
+ (shdr->sh_offset == end && shdr->sh_size != 0))
ERROR (gettext ("\
section [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"),
cnt, section_name (ebl, cnt), pcnt);
@@ -2223,29 +2813,34 @@ section [%2zu] '%s': ELF header says this is the section header string table but
switch (shdr->sh_type)
{
- case SHT_SYMTAB:
case SHT_DYNSYM:
- check_symtab (ebl, ehdr, cnt);
+ if (ehdr->e_type == ET_REL)
+ ERROR (gettext ("\
+section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
+ cnt, section_name (ebl, cnt));
+ /* FALLTHROUGH */
+ case SHT_SYMTAB:
+ check_symtab (ebl, ehdr, shdr, cnt);
break;
case SHT_RELA:
- check_rela (ebl, ehdr, cnt);
+ check_rela (ebl, ehdr, shdr, cnt);
break;
case SHT_REL:
- check_rel (ebl, ehdr, cnt);
+ check_rel (ebl, ehdr, shdr, cnt);
break;
case SHT_DYNAMIC:
- check_dynamic (ebl, cnt);
+ check_dynamic (ebl, shdr, cnt);
break;
case SHT_SYMTAB_SHNDX:
- check_symtab_shndx (ebl, cnt);
+ check_symtab_shndx (ebl, ehdr, shdr, cnt);
break;
case SHT_HASH:
- check_hash (ebl, cnt);
+ check_hash (ebl, ehdr, shdr, cnt);
break;
case SHT_NULL:
@@ -2257,7 +2852,20 @@ section [%2zu] '%s': ELF header says this is the section header string table but
break;
case SHT_GNU_versym:
- check_versym (ebl, shdr, cnt);
+ /* We cannot process this section now since we have no guarantee
+ that the verneed and verdef sections have already been read.
+ Just remember the section index. */
+ if (versym_scnndx != 0)
+ ERROR (gettext ("more than one version symbol table present\n"));
+ versym_scnndx = cnt;
+ break;
+
+ case SHT_GNU_verneed:
+ check_verneed (ebl, ehdr, shdr, cnt);
+ break;
+
+ case SHT_GNU_verdef:
+ check_verdef (ebl, shdr, cnt);
break;
default:
@@ -2269,6 +2877,39 @@ section [%2zu] '%s': ELF header says this is the section header string table but
if (has_interp_segment && !dot_interp_section)
ERROR (gettext ("INTERP program header entry but no .interp section\n"));
+ if (version_namelist != NULL)
+ {
+ if (versym_scnndx == 0)
+ ERROR (gettext ("\
+no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n"));
+ else
+ check_versym (ebl, versym_scnndx);
+
+ /* Check for duplicate index numbers. */
+ do
+ {
+ struct version_namelist *runp = version_namelist->next;
+ while (runp != NULL)
+ {
+ if (version_namelist->ndx == runp->ndx)
+ {
+ ERROR (gettext ("duplicate version index %d\n"),
+ (int) version_namelist->ndx);
+ break;
+ }
+ runp = runp->next;
+ }
+
+ struct version_namelist *old = version_namelist;
+ version_namelist = version_namelist->next;
+ free (old);
+ }
+ while (version_namelist != NULL);
+ }
+ else if (versym_scnndx != 0)
+ ERROR (gettext ("\
+.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"));
+
free (scnref);
}
@@ -2448,10 +3089,12 @@ only executables, shared objects, and core files can have program headers\n"));
}
if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME
- && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO)
+ && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO
+ /* Check for a known machine-specific type. */
+ && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL)
ERROR (gettext ("\
-program header entry %d: unknown program header entry type\n"),
- cnt);
+program header entry %d: unknown program header entry type %#" PRIx64 "\n"),
+ cnt, (uint64_t) phdr->p_type);
if (phdr->p_type == PT_LOAD)
has_loadable_segment = true;
@@ -2472,9 +3115,33 @@ more than one INTERP entry in program header\n"));
}
else if (phdr->p_type == PT_NOTE)
check_note (ebl, ehdr, phdr, cnt);
- else if (phdr->p_type == PT_DYNAMIC
- && ehdr->e_type == ET_EXEC && ! has_interp_segment)
- ERROR (gettext ("static executable cannot have dynamic sections\n"));
+ else if (phdr->p_type == PT_DYNAMIC)
+ {
+ if (ehdr->e_type == ET_EXEC && ! has_interp_segment)
+ ERROR (gettext ("\
+static executable cannot have dynamic sections\n"));
+ else
+ {
+ /* Check that the .dynamic section, if it exists, has
+ the same address. */
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
+ {
+ if (phdr->p_offset != shdr->sh_offset)
+ ERROR (gettext ("\
+dynamic section reference in program header has wrong offset\n"));
+ if (phdr->p_memsz != shdr->sh_size)
+ ERROR (gettext ("\
+dynamic section size mismatch in program and section header\n"));
+ break;
+ }
+ }
+ }
+ }
else if (phdr->p_type == PT_GNU_RELRO)
{
if (++num_pt_relro == 2)
@@ -2539,6 +3206,12 @@ process_elf_file (Elf *elf, const char *prefix, const char *suffix,
{
/* Reset variables. */
ndynamic = 0;
+ nverneed = 0;
+ nverdef = 0;
+ textrel = false;
+ needed_textrel = false;
+ has_loadable_segment = false;
+ has_interp_segment = false;
GElf_Ehdr ehdr_mem;
GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
@@ -2574,6 +3247,10 @@ process_elf_file (Elf *elf, const char *prefix, const char *suffix,
headers at all. */
check_sections (ebl, ehdr);
+ /* Report if no relocation section needed the text relocation flag. */
+ if (textrel && !needed_textrel)
+ ERROR (gettext ("text relocation flag set but not needed\n"));
+
/* Free the resources. */
ebl_closebackend (ebl);
}
diff --git a/elfutils/src/nm.c b/elfutils/src/nm.c
index 9d7dd070..2e3d1615 100644
--- a/elfutils/src/nm.c
+++ b/elfutils/src/nm.c
@@ -27,7 +27,6 @@
#include <gelf.h>
#include <inttypes.h>
#include <libdw.h>
-#include <libebl.h>
#include <libintl.h>
#include <locale.h>
#include <mcheck.h>
@@ -42,6 +41,7 @@
#include <sys/param.h>
#include <system.h>
+#include "../libebl/libeblP.h"
/* Name and version of program. */
@@ -507,13 +507,6 @@ static const int length_map[2][3] =
};
-struct global_name
-{
- Dwarf_Global global;
- const char *name;
-};
-
-
static int
global_compare (const void *p1, const void *p2)
{
diff --git a/elfutils/src/objdump.c b/elfutils/src/objdump.c
new file mode 100644
index 00000000..e571171e
--- /dev/null
+++ b/elfutils/src/objdump.c
@@ -0,0 +1,725 @@
+/* Print information from ELF file in human-readable form.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <error.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libintl.h>
+#include <locale.h>
+#include <mcheck.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include <system.h>
+#include "../libebl/libeblP.h"
+
+
+/* Name and version of program. */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+/* Bug report address. */
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
+
+/* Definitions of arguments for argp functions. */
+static const struct argp_option options[] =
+{
+ { NULL, 0, NULL, 0, N_("Mode selection:"), 0 },
+ { "reloc", 'r', NULL, 0, N_("Display relocation information."), 0 },
+ { "full-contents", 's', NULL, 0,
+ N_("Display the full contents of all sections requested"), 0 },
+ { "disassemble", 'd', NULL, 0,
+ N_("Display assembler code of executable sections"), 0 },
+
+ { NULL, 0, NULL, 0, N_("Output option selection:"), 0 },
+ { "section", 'j', "NAME", 0,
+ N_("Only display information for section NAME."), 0 },
+
+ { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program. */
+static const char doc[] = N_("\
+Show information from FILEs (a.out by default).");
+
+/* Strings for arguments in help texts. */
+static const char args_doc[] = N_("[FILE...]");
+
+/* Prototype for option handler. */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions. */
+static struct argp argp =
+{
+ options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* Print symbols in file named FNAME. */
+static int process_file (const char *fname, bool more_than_one);
+
+/* Handle content of archive. */
+static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+ const char *suffix);
+
+/* Handle ELF file. */
+static int handle_elf (Elf *elf, const char *prefix, const char *fname,
+ const char *suffix);
+
+
+#define INTERNAL_ERROR(fname) \
+ error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s-%s): %s"), \
+ fname, __LINE__, VERSION, __DATE__, elf_errmsg (-1))
+
+
+/* List of sections which should be used. */
+static struct section_list
+{
+ bool is_name;
+ union
+ {
+ const char *name;
+ uint32_t scnndx;
+ };
+ struct section_list *next;
+} *section_list;
+
+
+/* If true print archive index. */
+static bool print_relocs;
+
+/* If true print full contents of requested sections. */
+static bool print_full_content;
+
+/* If true print disassembled output.. */
+static bool print_disasm;
+
+int
+main (int argc, char *argv[])
+{
+ /* Make memory leak detection possible. */
+ mtrace ();
+
+ /* We use no threads here which can interfere with handling a stream. */
+ (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+ (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+ (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+ /* Set locale. */
+ (void) setlocale (LC_ALL, "");
+
+ /* Make sure the message catalog can be found. */
+ (void) bindtextdomain (PACKAGE, LOCALEDIR);
+
+ /* Initialize the message catalog. */
+ (void) textdomain (PACKAGE);
+
+ /* Parse and process arguments. */
+ int remaining;
+ (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+ /* Tell the library which version we are expecting. */
+ (void) elf_version (EV_CURRENT);
+
+ int result = 0;
+ if (remaining == argc)
+ /* The user didn't specify a name so we use a.out. */
+ result = process_file ("a.out", false);
+ else
+ {
+ /* Process all the remaining files. */
+ const bool more_than_one = remaining + 1 < argc;
+
+ do
+ result |= process_file (argv[remaining], more_than_one);
+ while (++remaining < argc);
+ }
+
+ return result;
+}
+
+
+/* Print the version information. */
+static void
+print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
+{
+ fprintf (stream, "objdump (%s) %s\n", PACKAGE_NAME, VERSION);
+ fprintf (stream, gettext ("\
+Copyright (C) %s Red Hat, Inc.\n\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "2005");
+ fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
+}
+
+
+/* Handle program arguments. */
+static error_t
+parse_opt (int key, char *arg,
+ struct argp_state *state __attribute__ ((unused)))
+{
+ /* True if any of the control options is set. */
+ static bool any_control_option;
+
+ switch (key)
+ {
+ case 'j':
+ {
+ struct section_list *newp = xmalloc (sizeof (*newp));
+ char *endp;
+ newp->scnndx = strtoul (arg, &endp, 0);
+ if (*endp == 0)
+ newp->is_name = false;
+ else
+ {
+ newp->name = arg;
+ newp->is_name = true;
+ }
+ newp->next = section_list;
+ section_list = newp;
+ }
+ any_control_option = true;
+ break;
+
+ case 'd':
+ print_disasm = true;
+ any_control_option = true;
+ break;
+
+ case 'r':
+ print_relocs = true;
+ any_control_option = true;
+ break;
+
+ case 's':
+ print_full_content = true;
+ any_control_option = true;
+ break;
+
+ case ARGP_KEY_FINI:
+ if (! any_control_option)
+ {
+ fputs (gettext ("No operation specified.\n"), stderr);
+ argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
+ program_invocation_short_name);
+ exit (1);
+ }
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+
+/* Open the file and determine the type. */
+static int
+process_file (const char *fname, bool more_than_one)
+{
+ /* Open the file. */
+ int fd = open (fname, O_RDONLY);
+ if (fd == -1)
+ {
+ error (0, errno, gettext ("cannot open %s"), fname);
+ return 1;
+ }
+
+ /* Now get the ELF descriptor. */
+ Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+ if (elf != NULL)
+ {
+ if (elf_kind (elf) == ELF_K_ELF)
+ {
+ int result = handle_elf (elf, more_than_one ? "" : NULL,
+ fname, NULL);
+
+ if (elf_end (elf) != 0)
+ INTERNAL_ERROR (fname);
+
+ if (close (fd) != 0)
+ error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
+
+ return result;
+ }
+ else if (elf_kind (elf) == ELF_K_AR)
+ {
+ int result = handle_ar (fd, elf, NULL, fname, NULL);
+
+ if (elf_end (elf) != 0)
+ INTERNAL_ERROR (fname);
+
+ if (close (fd) != 0)
+ error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
+
+ return result;
+ }
+
+ /* We cannot handle this type. Close the descriptor anyway. */
+ if (elf_end (elf) != 0)
+ INTERNAL_ERROR (fname);
+ }
+
+ error (0, 0, gettext ("%s: File format not recognized"), fname);
+
+ return 1;
+}
+
+
+static int
+handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+ const char *suffix)
+{
+ size_t fname_len = strlen (fname) + 1;
+ size_t prefix_len = prefix != NULL ? strlen (prefix) : 0;
+ char new_prefix[prefix_len + fname_len + 2];
+ size_t suffix_len = suffix != NULL ? strlen (suffix) : 0;
+ char new_suffix[suffix_len + 2];
+ Elf *subelf;
+ Elf_Cmd cmd = ELF_C_READ_MMAP;
+ int result = 0;
+
+ char *cp = new_prefix;
+ if (prefix != NULL)
+ cp = stpcpy (cp, prefix);
+ cp = stpcpy (cp, fname);
+ stpcpy (cp, "[");
+
+ cp = new_suffix;
+ if (suffix != NULL)
+ cp = stpcpy (cp, suffix);
+ stpcpy (cp, "]");
+
+ /* Process all the files contained in the archive. */
+ while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+ {
+ /* The the header for this element. */
+ Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+ /* Skip over the index entries. */
+ if (strcmp (arhdr->ar_name, "/") != 0
+ && strcmp (arhdr->ar_name, "//") != 0)
+ {
+ if (elf_kind (subelf) == ELF_K_ELF)
+ result |= handle_elf (subelf, new_prefix, arhdr->ar_name,
+ new_suffix);
+ else if (elf_kind (subelf) == ELF_K_AR)
+ result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name,
+ new_suffix);
+ else
+ {
+ error (0, 0, gettext ("%s%s%s: file format not recognized"),
+ new_prefix, arhdr->ar_name, new_suffix);
+ result = 1;
+ }
+ }
+
+ /* Get next archive element. */
+ cmd = elf_next (subelf);
+ if (elf_end (subelf) != 0)
+ INTERNAL_ERROR (fname);
+ }
+
+ return result;
+}
+
+
+static void
+show_relocs_rel (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
+ Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
+ size_t shstrndx)
+{
+ int elfclass = gelf_getclass (ebl->elf);
+ int nentries = shdr->sh_size / shdr->sh_entsize;
+
+ for (int cnt = 0; cnt < nentries; ++cnt)
+ {
+ GElf_Rel relmem;
+ GElf_Rel *rel;
+
+ rel = gelf_getrel (data, cnt, &relmem);
+ if (rel != NULL)
+ {
+ char buf[128];
+ GElf_Sym symmem;
+ GElf_Sym *sym;
+ Elf32_Word xndx;
+
+ sym = gelf_getsymshndx (symdata, xndxdata, GELF_R_SYM (rel->r_info),
+ &symmem, &xndx);
+ if (sym == NULL)
+ printf ("%0*" PRIx64 " %-20s <%s %ld>\n",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ gettext ("INVALID SYMBOL"),
+ (long int) GELF_R_SYM (rel->r_info));
+ else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ printf ("%0*" PRIx64 " %-20s %s\n",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ elf_strptr (ebl->elf, symstrndx, sym->st_name));
+ else
+ {
+ GElf_Shdr destshdr_mem;
+ GElf_Shdr *destshdr;
+ destshdr = gelf_getshdr (elf_getscn (ebl->elf,
+ sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx),
+ &destshdr_mem);
+
+ if (shdr == NULL)
+ printf ("%0*" PRIx64 " %-20s <%s %ld>\n",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ gettext ("INVALID SECTION"),
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+ printf ("%0*" PRIx64 " %-20s %s\n",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ }
+ }
+ }
+}
+
+
+static void
+show_relocs_rela (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
+ Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
+ size_t shstrndx)
+{
+ int elfclass = gelf_getclass (ebl->elf);
+ int nentries = shdr->sh_size / shdr->sh_entsize;
+
+ for (int cnt = 0; cnt < nentries; ++cnt)
+ {
+ GElf_Rela relmem;
+ GElf_Rela *rel;
+
+ rel = gelf_getrela (data, cnt, &relmem);
+ if (rel != NULL)
+ {
+ char buf[128];
+ GElf_Sym symmem;
+ GElf_Sym *sym;
+ Elf32_Word xndx;
+
+ sym = gelf_getsymshndx (symdata, xndxdata, GELF_R_SYM (rel->r_info),
+ &symmem, &xndx);
+ if (sym == NULL)
+ printf ("%0*" PRIx64 " %-20s <%s %ld>",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ gettext ("INVALID SYMBOL"),
+ (long int) GELF_R_SYM (rel->r_info));
+ else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ printf ("%0*" PRIx64 " %-20s %s",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ elf_strptr (ebl->elf, symstrndx, sym->st_name));
+ else
+ {
+ GElf_Shdr destshdr_mem;
+ GElf_Shdr *destshdr;
+ destshdr = gelf_getshdr (elf_getscn (ebl->elf,
+ sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx),
+ &destshdr_mem);
+
+ if (shdr == NULL)
+ printf ("%0*" PRIx64 " %-20s <%s %ld>",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ gettext ("INVALID SECTION"),
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+ printf ("%0*" PRIx64 " %-20s %s",
+ elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf))
+ : gettext ("<INVALID RELOC>"),
+ elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ }
+
+ if (rel->r_addend != 0)
+ printf ("+%#" PRIx64, rel->r_addend);
+ putchar ('\n');
+ }
+ }
+}
+
+
+static bool
+section_match (Elf *elf, uint32_t scnndx, GElf_Shdr *shdr, size_t shstrndx)
+{
+ if (section_list == NULL)
+ return true;
+
+ struct section_list *runp = section_list;
+
+ do
+ {
+ if (runp->is_name)
+ {
+ if (strcmp (runp->name,
+ elf_strptr (elf, shstrndx, shdr->sh_name)) == 0)
+ return true;
+ }
+ else
+ {
+ if (runp->scnndx == scnndx)
+ return true;
+ }
+
+ runp = runp->next;
+ }
+ while (runp != NULL);
+
+ return false;
+}
+
+
+static int
+show_relocs (Ebl *ebl, const char *fname, uint32_t shstrndx)
+{
+ int elfclass = gelf_getclass (ebl->elf);
+
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+ if (shdr == NULL)
+ INTERNAL_ERROR (fname);
+
+ if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+ {
+ if (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
+ continue;
+
+ GElf_Shdr destshdr_mem;
+ GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf,
+ shdr->sh_info),
+ &destshdr_mem);
+
+ printf (gettext ("RELOCATION RECORDS FOR [%s]:\n"
+ "%-*s TYPE VALUE\n"),
+ elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
+ elfclass == ELFCLASS32 ? 8 : 16, gettext ("OFFSET"));
+
+ /* Get the data of the section. */
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data == NULL)
+ continue;
+
+ /* Get the symbol table information. */
+ Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+ GElf_Shdr symshdr_mem;
+ GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+ Elf_Data *symdata = elf_getdata (symscn, NULL);
+
+ /* Search for the optional extended section index table. */
+ Elf_Data *xndxdata = NULL;
+ Elf_Scn *xndxscn = NULL;
+ while ((xndxscn = elf_nextscn (ebl->elf, xndxscn)) != NULL)
+ {
+ GElf_Shdr xndxshdr_mem;
+ GElf_Shdr *xndxshdr;
+
+ xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
+ if (xndxshdr != NULL && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
+ && xndxshdr->sh_link == elf_ndxscn (symscn))
+ {
+ /* Found it. */
+ xndxdata = elf_getdata (xndxscn, NULL);
+ break;
+ }
+ }
+
+ if (shdr->sh_type == SHT_REL)
+ show_relocs_rel (ebl, shdr, data, symdata, xndxdata,
+ symshdr->sh_link, shstrndx);
+ else
+ show_relocs_rela (ebl, shdr, data, symdata, xndxdata,
+ symshdr->sh_link, shstrndx);
+ }
+ }
+
+ fputs_unlocked ("\n\n", stdout);
+
+ return 0;
+}
+
+
+static int
+show_full_content (Ebl *ebl, const char *fname, uint32_t shstrndx)
+{
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+ if (shdr == NULL)
+ INTERNAL_ERROR (fname);
+
+ if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0)
+ {
+ if (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
+ continue;
+
+ printf (gettext ("Contents of section %s:\n"),
+ elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+
+ /* Get the data of the section. */
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data == NULL)
+ continue;
+
+ unsigned char *cp = data->d_buf;
+ size_t cnt;
+ for (cnt = 0; cnt + 16 < data->d_size; cp += 16, cnt += 16)
+ {
+ printf (" %04zx ", cnt);
+
+ for (size_t inner = 0; inner < 16; inner += 4)
+ printf ("%02hhx%02hhx%02hhx%02hhx ",
+ cp[inner], cp[inner + 1], cp[inner + 2],
+ cp[inner + 3]);
+ fputc_unlocked (' ', stdout);
+
+ for (size_t inner = 0; inner < 16; ++inner)
+ fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
+ ? cp[inner] : '.', stdout);
+ fputc_unlocked ('\n', stdout);
+ }
+
+ printf (" %04zx ", cnt);
+
+ size_t remaining = data->d_size - cnt;
+ size_t inner;
+ for (inner = 0; inner + 4 <= remaining; inner += 4)
+ printf ("%02hhx%02hhx%02hhx%02hhx ",
+ cp[inner], cp[inner + 1], cp[inner + 2], cp[inner + 3]);
+
+ for (; inner < remaining; ++inner)
+ printf ("%02hhx", cp[inner]);
+
+ for (inner = 2 * (16 - inner) + (16 - inner + 3) / 4 + 1; inner > 0;
+ --inner)
+ fputc_unlocked (' ', stdout);
+
+ for (inner = 0; inner < remaining; ++inner)
+ fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
+ ? cp[inner] : '.', stdout);
+ fputc_unlocked ('\n', stdout);
+
+ fputc_unlocked ('\n', stdout);
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+show_disasm (Ebl *ebl __attribute__ ((unused)),
+ const char *fname __attribute__ ((unused)),
+ uint32_t shstrndx __attribute__ ((unused)))
+{
+ /// XXX For now nothing.
+
+ return 0;
+}
+
+
+static int
+handle_elf (Elf *elf, const char *prefix, const char *fname,
+ const char *suffix)
+{
+
+ /* Get the backend for this object file type. */
+ Ebl *ebl = ebl_openbackend (elf);
+
+ printf (gettext ("%s: elf%d-%s\n\n"),
+ fname, gelf_getclass (elf) == ELFCLASS32 ? 32 : 64,
+ ebl_backend_name (ebl));
+
+ /* Create the full name of the file. */
+ size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+ size_t suffix_len = suffix == NULL ? 0 : strlen (suffix);
+ size_t fname_len = strlen (fname) + 1;
+ char fullname[prefix_len + 1 + fname_len + suffix_len];
+ char *cp = fullname;
+ if (prefix != NULL)
+ cp = mempcpy (cp, prefix, prefix_len);
+ cp = mempcpy (cp, fname, fname_len);
+ if (suffix != NULL)
+ memcpy (cp - 1, suffix, suffix_len + 1);
+
+ /* Get the section header string table index. */
+ size_t shstrndx;
+ if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot get section header string table index"));
+
+ int result = 0;
+ if (print_disasm)
+ result = show_disasm (ebl, fullname, shstrndx);
+ if (print_relocs && !print_disasm)
+ result = show_relocs (ebl, fullname, shstrndx);
+ if (print_full_content)
+ result = show_full_content (ebl, fullname, shstrndx);
+
+ /* Close the ELF backend library descriptor. */
+ ebl_closebackend (ebl);
+
+ return result;
+}
diff --git a/elfutils/src/ranlib.c b/elfutils/src/ranlib.c
new file mode 100644
index 00000000..ce2e6820
--- /dev/null
+++ b/elfutils/src/ranlib.c
@@ -0,0 +1,503 @@
+/* Generate an index to speed access to archives.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ar.h>
+#include <argp.h>
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libintl.h>
+#include <locale.h>
+#include <mcheck.h>
+#include <obstack.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <system.h>
+
+
+#define pread_retry(fd, buf, n, off) \
+ TEMP_FAILURE_RETRY (pread (fd, buf, n, off))
+#define write_retry(fd, buf, n) \
+ TEMP_FAILURE_RETRY (write (fd, buf, n))
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define le_bswap_32(val) bswap_32 (val)
+#else
+# define le_bswap_32(val) (val)
+#endif
+
+
+/* Prototypes for local functions. */
+static int handle_file (const char *fname);
+
+
+/* Name and version of program. */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+/* Bug report address. */
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
+
+/* Definitions of arguments for argp functions. */
+static const struct argp_option options[] =
+{
+ { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program. */
+static const char doc[] = N_("Generate an index to speed access to archives.");
+
+/* Strings for arguments in help texts. */
+static const char args_doc[] = N_("ARCHIVE");
+
+/* Prototype for option handler. */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions. */
+static struct argp argp =
+{
+ options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+int
+main (int argc, char *argv[])
+{
+ /* Make memory leak detection possible. */
+ mtrace ();
+
+ /* We use no threads here which can interfere with handling a stream. */
+ (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+ (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+ (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+ /* Set locale. */
+ (void) setlocale (LC_ALL, "");
+
+ /* Make sure the message catalog can be found. */
+ (void) bindtextdomain (PACKAGE, LOCALEDIR);
+
+ /* Initialize the message catalog. */
+ (void) textdomain (PACKAGE);
+
+ /* Parse and process arguments. */
+ int remaining;
+ (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
+
+ /* Tell the library which version we are expecting. */
+ (void) elf_version (EV_CURRENT);
+
+ /* There must at least be one more parameter specifying the archive. */
+ if (remaining == argc)
+ {
+ error (0, 0, gettext ("Archive name required"));
+ argp_help (&argp, stderr, ARGP_HELP_SEE, "ranlib");
+ exit (EXIT_FAILURE);
+ }
+
+ /* We accept the names of multiple archives. */
+ int status = 0;
+ do
+ status |= handle_file (argv[remaining]);
+ while (++remaining < argc);
+
+ return status;
+}
+
+
+/* Print the version information. */
+static void
+print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
+{
+ fprintf (stream, "ranlib (%s) %s\n", PACKAGE_NAME, VERSION);
+ fprintf (stream, gettext ("\
+Copyright (C) %s Red Hat, Inc.\n\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "2005");
+ fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
+}
+
+
+/* Handle program arguments. */
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+ struct argp_state *state __attribute__ ((unused)))
+{
+ switch (key)
+ {
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+
+static struct obstack offsob;
+size_t offs_len;
+static struct obstack namesob;
+size_t names_len;
+
+
+/* Add all exported, defined symbols from the given section to the table. */
+static void
+add_symbols (Elf *elf, const char *fname, off_t off, Elf_Scn *scn,
+ GElf_Shdr *shdr)
+{
+ if (sizeof (off) > sizeof (uint32_t) && off > ~((uint32_t) 0))
+ /* The archive is too big. */
+ error (EXIT_FAILURE, 0, gettext ("the archive '%s' is too large"), fname);
+
+ Elf_Data *data = elf_getdata (scn, NULL);
+ assert (data->d_size == shdr->sh_size);
+
+ /* We can skip the local symbols in the table. */
+ for (int cnt = shdr->sh_info; cnt < (int) (shdr->sh_size / shdr->sh_entsize);
+ ++cnt)
+ {
+ GElf_Sym sym_mem;
+ GElf_Sym *sym = gelf_getsym (data, cnt, &sym_mem);
+ if (sym == NULL)
+ /* Should never happen. */
+ continue;
+
+ /* Ignore undefined symbols. */
+ if (sym->st_shndx == SHN_UNDEF)
+ continue;
+
+ /* For all supported platforms the following is true. */
+ assert (sizeof (uint32_t) == sizeof (int));
+ obstack_int_grow (&offsob, (int) le_bswap_32 (off));
+ offs_len += sizeof (uint32_t);
+
+ const char *symname = elf_strptr (elf, shdr->sh_link, sym->st_name);
+ size_t symname_len = strlen (symname) + 1;
+ obstack_grow (&namesob, symname, symname_len);
+ names_len += symname_len;
+ }
+}
+
+
+/* Look through ELF file and collect all symbols available for
+ linking. If available, we use the dynamic symbol section.
+ Otherwise the normal one. Relocatable files are allowed to have
+ multiple symbol tables. */
+static void
+handle_elf (Elf *elf, const char *arfname, off_t off)
+{
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ assert (ehdr != NULL);
+
+ if (ehdr->e_type == ET_REL)
+ {
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr != NULL && shdr->sh_type == SHT_SYMTAB)
+ add_symbols (elf, arfname, off, scn, shdr);
+ }
+ }
+ else
+ {
+ Elf_Scn *symscn = NULL;
+ GElf_Shdr *symshdr = NULL;
+ Elf_Scn *scn = NULL;
+ GElf_Shdr shdr_mem;
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
+ {
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ symshdr = NULL;
+ if (shdr != NULL)
+ {
+ if (shdr->sh_type == SHT_DYNSYM)
+ {
+ symscn = scn;
+ symshdr = shdr;
+ break;
+ }
+ if (shdr->sh_type == SHT_SYMTAB)
+ {
+ /* There better be only one symbol table in
+ executables in DSOs. */
+ assert (symscn == NULL);
+ symscn = scn;
+ symshdr = shdr;
+ }
+ }
+ }
+
+ add_symbols (elf, arfname, off, symscn,
+ symshdr ?: gelf_getshdr (scn, &shdr_mem));
+ }
+}
+
+
+static int
+copy_content (int oldfd, int newfd, off_t off, size_t n)
+{
+ while (n > 0)
+ {
+ char buf[32768];
+
+ ssize_t nread = pread_retry (oldfd, buf, MIN (sizeof (buf), n), off);
+ if (unlikely (nread <= 0))
+ return 1;
+
+ if (write_retry (newfd, buf, nread) != nread)
+ return 1;
+
+ n -= nread;
+ off += nread;
+ }
+
+ return 0;
+}
+
+
+/* Handle a file given on the command line. */
+static int
+handle_file (const char *fname)
+{
+ int fd = open (fname, O_RDONLY);
+ if (fd == -1)
+ {
+ error (0, errno, gettext ("cannot open '%s'"), fname);
+ return 1;
+ }
+
+ struct stat st;
+ if (fstat (fd, &st) != 0)
+ {
+ error (0, errno, gettext ("cannot stat '%s'"), fname);
+ close (fd);
+ return 1;
+ }
+
+ /* First we walk through the file, looking for all ELF files to
+ collect symbols from. */
+ Elf *arelf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+ if (arelf == NULL)
+ {
+ error (0, 0, gettext ("cannot create ELF descriptor for '%s': %s"),
+ fname, elf_errmsg (-1));
+ close (fd);
+ return 1;
+ }
+
+ if (elf_kind (arelf) != ELF_K_AR)
+ {
+ error (0, 0, gettext ("'%s' is no archive"), fname);
+ elf_end (arelf);
+ close (fd);
+ return 1;
+ }
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+ obstack_init (&offsob);
+ offs_len = 0;
+ obstack_init (&namesob);
+ names_len = 0;
+
+ /* The first word in the offset table specifies the size. Create
+ such an entry now. The real value will be filled-in later. For
+ all supported platforms the following is true. */
+ assert (sizeof (uint32_t) == sizeof (int));
+ obstack_int_grow (&offsob, 0);
+ offs_len += sizeof (uint32_t);
+
+ /* Iterate over the content of the archive. */
+ off_t index_off = -1;
+ size_t index_size = 0;
+ Elf *elf;
+ Elf_Cmd cmd = ELF_C_READ_MMAP;
+ while ((elf = elf_begin (fd, cmd, arelf)) != NULL)
+ {
+ Elf_Arhdr *arhdr = elf_getarhdr (elf);
+ assert (arhdr != NULL);
+ off_t off = elf_getaroff (elf);
+
+ Elf_Kind kind = elf_kind (elf);
+ if (kind == ELF_K_ELF)
+ handle_elf (elf, fname, off);
+#if 0
+ else if (kind == ELF_K_AR)
+ {
+ // XXX Should we implement this?
+ }
+#endif
+ /* If this is the index, remember the location. */
+ else if (strcmp (arhdr->ar_name, "/") == 0)
+ {
+ index_off = off;
+ index_size = arhdr->ar_size;
+ }
+
+ /* Get next archive element. */
+ cmd = elf_next (elf);
+ if (elf_end (elf) != 0)
+ error (0, 0,
+ gettext (" error while freeing sub-ELF descriptor: %s\n"),
+ elf_errmsg (-1));
+ }
+
+ elf_end (arelf);
+ uint32_t *offs_arr = obstack_finish (&offsob);
+ assert (offs_len % sizeof (uint32_t) == 0);
+ if ((names_len & 1) != 0)
+ {
+ /* Add one more NUL byte to make length even. */
+ obstack_grow (&namesob, "", 1);
+ ++names_len;
+ }
+ const char *names_str = obstack_finish (&namesob);
+
+ /* If the file contains no symbols we need not do anything. */
+ if (names_len != 0
+ /* We have to rewrite the file also if it initially had an index
+ but now does not need one anymore. */
+ || (names_len == 0 && index_off != -1))
+ {
+ /* Create a new, temporary file in the same directory as the
+ original file. */
+ char tmpfname[strlen (fname) + 8];
+ strcpy (stpcpy (tmpfname, fname), ".XXXXXX");
+ int newfd = mkstemp (tmpfname);
+ if (newfd == -1)
+ nonew:
+ error (0, errno, gettext ("cannot create new file"));
+ else
+ {
+ /* Create the header. */
+ if (write_retry (newfd, ARMAG, SARMAG) != SARMAG)
+ {
+ // XXX Use /prof/self/fd/%d ???
+ nonew_unlink:
+ unlink (tmpfname);
+ if (newfd != -1)
+ close (newfd);
+ goto nonew;
+ }
+
+ struct ar_hdr ar_hdr;
+ memcpy (ar_hdr.ar_name, "/ ", sizeof (ar_hdr.ar_name));
+ /* Using snprintf here has a problem: the call always wants
+ to add a NUL byte. We could use a trick whereby we
+ specify the target buffer size longer than it is and this
+ would not actually fail, since all the fields are
+ consecutive and we fill them in in sequence (i.e., the
+ NUL byte gets overwritten). But _FORTIFY_SOURCE=2 would
+ not let us play these games. Therefore we play it
+ safe. */
+ char tmpbuf[MAX (sizeof (ar_hdr.ar_date), sizeof (ar_hdr.ar_size))
+ + 1];
+ memcpy (ar_hdr.ar_date, tmpbuf,
+ snprintf (tmpbuf, sizeof (tmpbuf), "%-*lld",
+ (int) sizeof (ar_hdr.ar_date),
+ (long long int) time (NULL)));
+
+ /* Note the string for the ar_uid and ar_gid cases is longer
+ than necessary. This does not matter since we copy only as
+ much as necessary but it helps the compiler to use the same
+ string for the ar_mode case. */
+ memcpy (ar_hdr.ar_uid, "0 ", sizeof (ar_hdr.ar_uid));
+ memcpy (ar_hdr.ar_gid, "0 ", sizeof (ar_hdr.ar_gid));
+ memcpy (ar_hdr.ar_mode, "0 ", sizeof (ar_hdr.ar_mode));
+
+ /* See comment for ar_date above. */
+ memcpy (ar_hdr.ar_size, tmpbuf,
+ snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu",
+ (int) sizeof (ar_hdr.ar_size),
+ offs_len + names_len));
+ memcpy (ar_hdr.ar_fmag, ARFMAG, sizeof (ar_hdr.ar_fmag));
+
+ /* Fill in the number of offsets now. */
+ offs_arr[0] = le_bswap_32 (offs_len / sizeof (uint32_t) - 1);
+
+ /* Adjust the offset values for the name index size (if
+ necessary). */
+ off_t disp = (offs_len + ((names_len + 1) & ~1ul)
+ - ((index_size + 1) & ~1ul));
+ /* If there was no index so far but one is needed now we
+ have to take the archive header into account. */
+ if (index_off == -1 && names_len != 0)
+ disp += sizeof (struct ar_hdr);
+ if (disp != 0)
+ for (size_t cnt = 1; cnt < offs_len / sizeof (uint32_t); ++cnt)
+ {
+ uint32_t val;
+ val = le_bswap_32 (offs_arr[cnt]);
+
+ if (val > index_off)
+ {
+ val += disp;
+ offs_arr[cnt] = le_bswap_32 (val);
+ }
+ }
+
+ /* Create the new file. There are three parts as far we are
+ concerned: 1. original context before the index, 2. the
+ new index, 3. everything after the new index. */
+ off_t rest_off;
+ if (index_off != -1)
+ rest_off = (index_off + sizeof (struct ar_hdr)
+ + ((index_size + 1) & ~1ul));
+ else
+ rest_off = SARMAG;
+
+ if ((index_off > SARMAG
+ && copy_content (fd, newfd, SARMAG, index_off - SARMAG))
+ || (names_len != 0
+ && ((write_retry (newfd, &ar_hdr, sizeof (ar_hdr))
+ != sizeof (ar_hdr))
+ || (write_retry (newfd, offs_arr, offs_len)
+ != (ssize_t) offs_len)
+ || (write_retry (newfd, names_str, names_len)
+ != (ssize_t) names_len)))
+ || copy_content (fd, newfd, rest_off, st.st_size - rest_off)
+ /* Set the mode of the new file to the same values the
+ original file has. */
+ || fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ || fchown (newfd, st.st_uid, st.st_gid) != 0
+ || close (newfd) != 0
+ || (newfd = -1, rename (tmpfname, fname) != 0))
+ goto nonew_unlink;
+ }
+ }
+
+ obstack_free (&offsob, NULL);
+ obstack_free (&namesob, NULL);
+
+ close (fd);
+
+ return 0;
+}
diff --git a/elfutils/src/readelf.c b/elfutils/src/readelf.c
index 8386a397..ac902cd3 100644
--- a/elfutils/src/readelf.c
+++ b/elfutils/src/readelf.c
@@ -26,7 +26,6 @@
#include <inttypes.h>
#include <langinfo.h>
#include <libdw.h>
-#include <libebl.h>
#include <libintl.h>
#include <locale.h>
#include <stdbool.h>
@@ -37,6 +36,7 @@
#include <sys/param.h>
#include <system.h>
+#include "../libebl/libeblP.h"
#include "../libdw/libdwP.h"
#include "../libdw/memory-access.h"
@@ -64,7 +64,8 @@ static const struct argp_option options[] =
{ "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
{ "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
N_("Display DWARF section content. SECTION can be one of abbrev, "
- "aranges, frame, info, loc, line, pubnames, str, or macinfo."), 0 },
+ "aranges, frame, info, loc, line, ranges, pubnames, str, or macinfo."),
+ 0 },
{ "notes", 'n', NULL, 0, N_("Display the core notes"), 0 },
{ "arch-specific", 'A', NULL, 0,
N_("Display architecture specific information (if any)"), 0 },
@@ -138,9 +139,11 @@ static enum section_e
section_pubnames = 64,/* .debug_pubnames */
section_str = 128, /* .debug_str */
section_macinfo = 256,/* .debug_macinfo */
+ section_ranges = 512, /* .debug_ranges */
section_all = (section_abbrev | section_aranges | section_frame
| section_info | section_line | section_loc
- | section_pubnames | section_str | section_macinfo)
+ | section_pubnames | section_str | section_macinfo
+ | section_ranges)
} print_debug_sections;
/* Number of sections in the file. */
@@ -156,7 +159,7 @@ static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_scngrp (Ebl *ebl);
-static void print_dynamic (Ebl *ebl);
+static void print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_relocs (Ebl *ebl);
static void handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
static void handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
@@ -299,6 +302,8 @@ parse_opt (int key, char *arg,
print_debug_sections |= section_abbrev;
else if (strcmp (arg, "aranges") == 0)
print_debug_sections |= section_aranges;
+ else if (strcmp (arg, "ranges") == 0)
+ print_debug_sections |= section_ranges;
else if (strcmp (arg, "frame") == 0)
print_debug_sections |= section_frame;
else if (strcmp (arg, "info") == 0)
@@ -474,7 +479,7 @@ process_elf_file (Elf *elf, const char *prefix, const char *fname,
if (print_section_groups)
print_scngrp (ebl);
if (print_dynamic_table)
- print_dynamic (ebl);
+ print_dynamic (ebl, ehdr);
if (print_relocations)
print_relocs (ebl);
if (print_histogram)
@@ -1259,20 +1264,20 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
/* Print the dynamic segment. */
static void
-print_dynamic (Ebl *ebl)
+print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr)
{
- /* Find all relocation sections and handle them. */
- Elf_Scn *scn = NULL;
-
- while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+ for (int i = 0; i < ehdr->e_phnum; ++i)
{
- /* Handle the section if it is a symbol table. */
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
- if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
+ if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
{
- handle_dynamic (ebl, scn, shdr);
+ Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
+ handle_dynamic (ebl, scn, shdr);
break;
}
}
@@ -1938,23 +1943,20 @@ get_ver_flags (unsigned int flags)
static void
handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
- Elf_Data *data;
int class = gelf_getclass (ebl->elf);
- GElf_Shdr glink;
- int cnt;
- unsigned int offset;
- size_t shstrndx;
/* Get the data of the section. */
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL)
return;
/* Get the section header string table index. */
+ size_t shstrndx;
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
+ GElf_Shdr glink;
printf (ngettext ("\
\nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
@@ -1969,16 +1971,12 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
&glink)->sh_name));
- offset = 0;
- for (cnt = shdr->sh_info; --cnt >= 0; )
+ unsigned int offset = 0;
+ for (int cnt = shdr->sh_info; --cnt >= 0; )
{
- GElf_Verneed needmem;
- GElf_Verneed *need;
- unsigned int auxoffset;
- int cnt2;
-
/* Get the data at the next offset. */
- need = gelf_getverneed (data, offset, &needmem);
+ GElf_Verneed needmem;
+ GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
if (need == NULL)
break;
@@ -1987,13 +1985,11 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
(unsigned short int) need->vn_cnt);
- auxoffset = offset + need->vn_aux;
- for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
+ unsigned int auxoffset = offset + need->vn_aux;
+ for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
{
GElf_Vernaux auxmem;
- GElf_Vernaux *aux;
-
- aux = gelf_getvernaux (data, auxoffset, &auxmem);
+ GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
if (aux == NULL)
break;
@@ -2015,23 +2011,19 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
static void
handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
- Elf_Data *data;
- int class = gelf_getclass (ebl->elf);
- GElf_Shdr glink;
- int cnt;
- unsigned int offset;
- size_t shstrndx;
-
/* Get the data of the section. */
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL)
return;
/* Get the section header string table index. */
+ size_t shstrndx;
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
+ int class = gelf_getclass (ebl->elf);
+ GElf_Shdr glink;
printf (ngettext ("\
\nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
@@ -2047,23 +2039,18 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
&glink)->sh_name));
- offset = 0;
- for (cnt = shdr->sh_info; --cnt >= 0; )
+ unsigned int offset = 0;
+ for (int cnt = shdr->sh_info; --cnt >= 0; )
{
- GElf_Verdef defmem;
- GElf_Verdef *def;
- GElf_Verdaux auxmem;
- GElf_Verdaux *aux;
- unsigned int auxoffset;
- int cnt2;
-
/* Get the data at the next offset. */
- def = gelf_getverdef (data, offset, &defmem);
+ GElf_Verdef defmem;
+ GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
if (def == NULL)
break;
- auxoffset = offset + def->vd_aux;
- aux = gelf_getverdaux (data, auxoffset, &auxmem);
+ unsigned int auxoffset = offset + def->vd_aux;
+ GElf_Verdaux auxmem;
+ GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
if (aux == NULL)
break;
@@ -2076,7 +2063,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
auxoffset += aux->vda_next;
- for (cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
+ for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
{
aux = gelf_getverdaux (data, auxoffset, &auxmem);
if (aux == NULL)
@@ -2098,34 +2085,28 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
static void
handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
- Elf_Data *data;
int class = gelf_getclass (ebl->elf);
- Elf_Scn *verscn;
GElf_Shdr glink;
- Elf_Scn *defscn;
- Elf_Scn *needscn;
const char **vername;
const char **filename;
- size_t nvername;
- unsigned int cnt;
- size_t shstrndx;
/* Get the data of the section. */
- data = elf_getdata (scn, NULL);
+ Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL)
return;
/* Get the section header string table index. */
+ size_t shstrndx;
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
/* We have to find the version definition section and extract the
version names. */
- defscn = NULL;
- needscn = NULL;
+ Elf_Scn *defscn = NULL;
+ Elf_Scn *needscn = NULL;
- verscn = NULL;
+ Elf_Scn *verscn = NULL;
while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
{
GElf_Shdr vershdr_mem;
@@ -2140,6 +2121,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
}
}
+ size_t nvername;
if (defscn != NULL || needscn != NULL)
{
/* We have a version information (better should have). Now get
@@ -2162,7 +2144,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
if (defshdr == NULL)
return;
- for (cnt = 0; cnt < defshdr->sh_info; ++cnt)
+ for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
{
GElf_Verdef defmem;
GElf_Verdef *def;
@@ -2192,7 +2174,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
if (needshdr == NULL)
return;
- for (cnt = 0; cnt < needshdr->sh_info; ++cnt)
+ for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
{
GElf_Verneed needmem;
GElf_Verneed *need;
@@ -2250,7 +2232,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
if (defshdr == NULL)
return;
- for (cnt = 0; cnt < defshdr->sh_info; ++cnt)
+ for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
{
GElf_Verdef defmem;
GElf_Verdef *def;
@@ -2288,7 +2270,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
if (needshdr == NULL)
return;
- for (cnt = 0; cnt < needshdr->sh_info; ++cnt)
+ for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
{
GElf_Verneed needmem;
GElf_Verneed *need;
@@ -2347,7 +2329,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
&glink)->sh_name));
/* Now we can finally look at the actual contents of this section. */
- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+ for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
{
GElf_Versym symmem;
GElf_Versym *sym;
@@ -2629,6 +2611,18 @@ dwarf_tag_string (unsigned int tag)
[DW_TAG_variant_part] = "variant_part",
[DW_TAG_variable] = "variable",
[DW_TAG_volatile_type] = "volatile_type",
+ [DW_TAG_dwarf_procedure] = "dwarf_procedure",
+ [DW_TAG_restrict_type] = "restrict_type",
+ [DW_TAG_interface_type] = "interface_type",
+ [DW_TAG_namespace] = "namespace",
+ [DW_TAG_imported_module] = "imported_module",
+ [DW_TAG_unspecified_type] = "unspecified_type",
+ [DW_TAG_partial_unit] = "partial_unit",
+ [DW_TAG_imported_unit] = "imported_unit",
+ [DW_TAG_unspecified_type] = "unspecified_type",
+ [DW_TAG_partial_unit] = "partial_unit",
+ [DW_TAG_imported_unit] = "imported_unit",
+ [DW_TAG_mutable_type] = "mutable_type",
};
const unsigned int nknown_tags = (sizeof (known_tags)
/ sizeof (known_tags[0]));
@@ -2737,7 +2731,20 @@ dwarf_attr_string (unsigned int attrnum)
[DW_AT_use_location] = "use_location",
[DW_AT_variable_parameter] = "variable_parameter",
[DW_AT_virtuality] = "virtuality",
- [DW_AT_vtable_elem_location] = "vtable_elem_location"
+ [DW_AT_vtable_elem_location] = "vtable_elem_location",
+ [DW_AT_allocated] = "allocated",
+ [DW_AT_associated] = "associated",
+ [DW_AT_data_location] = "data_location",
+ [DW_AT_stride] = "stride",
+ [DW_AT_entry_pc] = "entry_pc",
+ [DW_AT_use_UTF8] = "use_UTF8",
+ [DW_AT_extension] = "extension",
+ [DW_AT_ranges] = "ranges",
+ [DW_AT_trampoline] = "trampoline",
+ [DW_AT_call_column] = "call_column",
+ [DW_AT_call_file] = "call_file",
+ [DW_AT_call_line] = "call_line",
+ [DW_AT_description] = "description"
};
const unsigned int nknown_attrs = (sizeof (known_attrs)
/ sizeof (known_attrs[0]));
@@ -3115,8 +3122,8 @@ dwarf_discr_list_string (unsigned int code)
static void
-print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
- unsigned char *data)
+print_ops (Dwarf *dbg, int indent, int indentrest,
+ unsigned int addrsize, Dwarf_Word len, const unsigned char *data)
{
static const char *known[] =
{
@@ -3274,8 +3281,7 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
Dwarf_Word offset = 0;
while (len-- > 0)
{
- size_t op = *((unsigned char *) data);
- ++data;
+ size_t op = *data++;
switch (op)
{
@@ -3293,8 +3299,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
data += addrsize;
len -= addrsize;
- printf (" %*s [%4" PRIuMAX "] %s %" PRIuMAX "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", (uintmax_t) addr);
offset += 1 + addrsize;
break;
@@ -3303,8 +3309,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
case DW_OP_xderef_size: /* XXX Correct? */
case DW_OP_pick:
case DW_OP_const1u:
- printf (" %*s [%4" PRIuMAX "] %s %" PRIu8 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", *((uint8_t *) data));
++data;
--len;
@@ -3312,8 +3318,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
break;
case DW_OP_const2u:
- printf (" %*s [%4" PRIuMAX "] %s %" PRIu16 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", read_2ubyte_unaligned (dbg, data));
len -= 2;
data += 2;
@@ -3321,8 +3327,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
break;
case DW_OP_const4u:
- printf (" %*s [%4" PRIuMAX "] %s %" PRIu32 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", read_4ubyte_unaligned (dbg, data));
len -= 4;
data += 4;
@@ -3330,8 +3336,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
break;
case DW_OP_const8u:
- printf (" %*s [%4" PRIuMAX "] %s %" PRIu64 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", read_8ubyte_unaligned (dbg, data));
len -= 8;
data += 8;
@@ -3339,8 +3345,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
break;
case DW_OP_const1s:
- printf (" %*s [%4" PRIuMAX "] %s %" PRId8 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", *((int8_t *) data));
++data;
--len;
@@ -3348,8 +3354,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
break;
case DW_OP_const2s:
- printf (" %*s [%4" PRIuMAX "] %s %" PRId16 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", read_2sbyte_unaligned (dbg, data));
len -= 2;
data += 2;
@@ -3357,8 +3363,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
break;
case DW_OP_const4s:
- printf (" %*s [%4" PRIuMAX "] %s %" PRId32 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", read_4sbyte_unaligned (dbg, data));
len -= 4;
data += 4;
@@ -3366,8 +3372,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
break;
case DW_OP_const8s:
- printf (" %*s [%4" PRIuMAX "] %s %" PRId64 "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", read_8sbyte_unaligned (dbg, data));
len -= 8;
data += 8;
@@ -3378,11 +3384,11 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
case DW_OP_regx:
case DW_OP_plus_uconst:
case DW_OP_constu:;
- unsigned char *start = data;
+ const unsigned char *start = data;
unsigned int uleb;
get_uleb128 (uleb, data);
- printf (" %*s [%4" PRIuMAX "] %s %u\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %u\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", uleb);
len -= data - start;
offset += 1 + (data - start);
@@ -3394,8 +3400,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
start = data;
unsigned int sleb;
get_sleb128 (sleb, data);
- printf (" %*s [%4" PRIuMAX "] %s %d\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %d\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", sleb);
len -= data - start;
offset += 1 + (data - start);
@@ -3405,8 +3411,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
start = data;
get_uleb128 (uleb, data);
get_sleb128 (sleb, data);
- printf (" %*s [%4" PRIuMAX "] %s %u %d\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %u %d\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???", uleb, sleb);
len -= data - start;
offset += 1 + (data - start);
@@ -3416,8 +3422,8 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
case DW_OP_call4:
case DW_OP_skip:
case DW_OP_bra:
- printf (" %*s [%4" PRIuMAX "] %s %" PRIuMAX "\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???",
(uintmax_t) (offset + read_2sbyte_unaligned (dbg, data)));
len -= 2;
@@ -3427,12 +3433,14 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
default:
/* No Operand. */
- printf (" %*s [%4" PRIuMAX "] %s\n",
- (int) (20 + level * 2), "", (uintmax_t) offset,
+ printf ("%*s[%4" PRIuMAX "] %s\n",
+ indent, "", (uintmax_t) offset,
known[op] ?: "???");
++offset;
break;
}
+
+ indent = indentrest;
}
}
@@ -3448,49 +3456,59 @@ print_debug_abbrev_section (Ebl *ebl __attribute__ ((unused)),
".debug_abbrev", (uint64_t) shdr->sh_offset);
Dwarf_Off offset = 0;
- while (1)
+ while (offset < shdr->sh_size)
{
- size_t length;
- Dwarf_Abbrev abbrev;
+ printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
+ offset);
- int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
- if (res != 0)
+ while (1)
{
- if (res < 0)
- printf (gettext (" *** error while reading abbreviation: %s\n"),
- dwarf_errmsg (-1));
- break;
- }
+ size_t length;
+ Dwarf_Abbrev abbrev;
- if (length == 1)
- /* This is the NUL byte at the end of the section. */
- break;
+ int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
+ if (res != 0)
+ {
+ if (res < 0)
+ {
+ printf (gettext ("\
+ *** error while reading abbreviation: %s\n"),
+ dwarf_errmsg (-1));
+ return;
+ }
- /* We know these calls can never fail. */
- unsigned int code = dwarf_getabbrevcode (&abbrev);
- unsigned int tag = dwarf_getabbrevtag (&abbrev);
- int has_children = dwarf_abbrevhaschildren (&abbrev);
-
- printf (gettext (" [%5u] offset: %" PRId64
- ", children: %s, tag: %s\n"),
- code, (int64_t) offset,
- has_children ? gettext ("yes") : gettext ("no"),
- dwarf_tag_string (tag));
-
- size_t cnt = 0;
- unsigned int name;
- unsigned int form;
- Dwarf_Off enoffset;
- while (dwarf_getabbrevattr (&abbrev, cnt, &name, &form, &enoffset) == 0)
- {
- printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
- dwarf_attr_string (name), dwarf_form_string (form),
- (uint64_t) enoffset);
+ /* This is the NUL byte at the end of the section. */
+ ++offset;
+ break;
+ }
- ++cnt;
- }
+ /* We know these calls can never fail. */
+ unsigned int code = dwarf_getabbrevcode (&abbrev);
+ unsigned int tag = dwarf_getabbrevtag (&abbrev);
+ int has_children = dwarf_abbrevhaschildren (&abbrev);
+
+ printf (gettext (" [%5u] offset: %" PRId64
+ ", children: %s, tag: %s\n"),
+ code, (int64_t) offset,
+ has_children ? gettext ("yes") : gettext ("no"),
+ dwarf_tag_string (tag));
+
+ size_t cnt = 0;
+ unsigned int name;
+ unsigned int form;
+ Dwarf_Off enoffset;
+ while (dwarf_getabbrevattr (&abbrev, cnt,
+ &name, &form, &enoffset) == 0)
+ {
+ printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
+ dwarf_attr_string (name), dwarf_form_string (form),
+ (uint64_t) enoffset);
+
+ ++cnt;
+ }
- offset += length;
+ offset += length;
+ }
}
}
@@ -3553,6 +3571,76 @@ print_debug_aranges_section (Ebl *ebl __attribute__ ((unused)),
}
}
+/* Print content of DWARF .debug_ranges section. */
+static void
+print_debug_ranges_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr,
+ Dwarf *dbg)
+{
+ Elf_Data *data = elf_rawdata (scn, NULL);
+
+ if (data == NULL)
+ {
+ error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
+ elf_errmsg (-1));
+ return;
+ }
+
+ printf (gettext ("\
+\nDWARF section '%s' at offset %#" PRIx64 ":\n"),
+ ".debug_ranges", (uint64_t) shdr->sh_offset);
+
+ size_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+ bool first = true;
+ unsigned char *readp = data->d_buf;
+ while (readp < (unsigned char *) data->d_buf + data->d_size)
+ {
+ ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
+
+ if (data->d_size - offset < address_size * 2)
+ {
+ printf (" [%6tx] <INVALID DATA>\n", offset);
+ break;
+ }
+
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+ if (address_size == 8)
+ {
+ begin = read_8ubyte_unaligned_inc (dbg, readp);
+ end = read_8ubyte_unaligned_inc (dbg, readp);
+ }
+ else
+ {
+ begin = read_4ubyte_unaligned_inc (dbg, readp);
+ end = read_4ubyte_unaligned_inc (dbg, readp);
+ if (begin == (Dwarf_Addr) (uint32_t) -1)
+ begin = (Dwarf_Addr) -1l;
+ }
+
+ if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
+ printf (" [%6tx] base address %#0*" PRIxMAX "\n", offset,
+ 2 + (int) (address_size * 2), (uintmax_t) end);
+ else if (begin == 0 && end == 0) /* End of list entry. */
+ first = true;
+ else
+ {
+ /* We have an address range entry. */
+ if (first) /* First address range entry in a list. */
+ printf (" [%6tx] %#0*" PRIxMAX "..%#0*" PRIxMAX "\n", offset,
+ 2 + (int) (address_size * 2), (uintmax_t) begin,
+ 2 + (int) (address_size * 2), (uintmax_t) end);
+ else
+ printf (" %#0*" PRIxMAX "..%#0*" PRIxMAX "\n",
+ 2 + (int) (address_size * 2), (uintmax_t) begin,
+ 2 + (int) (address_size * 2), (uintmax_t) end);
+
+ first = false;
+ }
+ }
+}
+
static void
print_debug_frame_section (Ebl *ebl __attribute__ ((unused)),
@@ -3608,7 +3696,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
}
printf (" %*s%-20s %#0*" PRIxMAX "\n",
(int) (level * 2), "", dwarf_attr_string (attr),
- (int) (cbargs->addrsize * 2), (uintmax_t) addr);
+ 2 + (int) (cbargs->addrsize * 2), (uintmax_t) addr);
break;
case DW_FORM_indirect:
@@ -3649,6 +3737,25 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
const char *valuestr = NULL;
switch (attr)
{
+ case DW_AT_location:
+ case DW_AT_data_member_location:
+ case DW_AT_vtable_elem_location:
+ case DW_AT_string_length:
+ case DW_AT_use_location:
+ case DW_AT_frame_base:
+ case DW_AT_return_addr:
+ case DW_AT_static_link:
+ printf (" %*s%-20s location list [%6" PRIxMAX "]\n",
+ (int) (level * 2), "", dwarf_attr_string (attr),
+ (uintmax_t) num);
+ return DWARF_CB_OK;
+
+ case DW_AT_ranges:
+ printf (" %*s%-20s range list [%6" PRIxMAX "]\n",
+ (int) (level * 2), "", dwarf_attr_string (attr),
+ (uintmax_t) num);
+ return DWARF_CB_OK;
+
case DW_AT_language:
valuestr = dwarf_lang_string (num);
break;
@@ -3680,7 +3787,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
valuestr = dwarf_discr_list_string (num);
break;
default:
- /* Noting. */
+ /* Nothing. */
break;
}
@@ -3716,9 +3823,20 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
(int) (level * 2), "", dwarf_attr_string (attr),
(uintmax_t) block.length);
- if (attr == DW_AT_data_member_location)
- print_ops (cbargs->dbg, level, cbargs->addrsize, block.length,
- block.data);
+ switch (attr)
+ {
+ case DW_AT_location:
+ case DW_AT_data_member_location:
+ case DW_AT_vtable_elem_location:
+ case DW_AT_string_length:
+ case DW_AT_use_location:
+ case DW_AT_frame_base:
+ case DW_AT_return_addr:
+ case DW_AT_static_link:
+ print_ops (cbargs->dbg, 12 + level * 2, 12 + level * 2,
+ cbargs->addrsize, block.length, block.data);
+ break;
+ }
break;
default:
@@ -3805,6 +3923,9 @@ print_debug_info_section (Ebl *ebl __attribute__ ((unused)),
goto do_return;
}
+#if 1
+ const char *tagstr = dwarf_tag_string (tag);
+#else
static const char *const lowtags[] =
{
[DW_TAG_array_type] = "array_type",
@@ -3889,6 +4010,7 @@ print_debug_info_section (Ebl *ebl __attribute__ ((unused)),
tagstr = "???";
break;
}
+#endif
printf (" [%6" PRIx64 "] %*s%s\n",
(uint64_t) offset, (int) (level * 2), "", tagstr);
@@ -3966,6 +4088,8 @@ print_debug_line_section (Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
{
size_t start_offset = linep - (const unsigned char *) data->d_buf;
+ printf (gettext ("\nTable at offset %Zu:\n"), start_offset);
+
Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
unsigned int length = 4;
if (unlikely (unit_length == 0xffffffff))
@@ -4227,7 +4351,7 @@ define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
break;
}
}
- else if (opcode <= DW_LNS_set_epilog_begin)
+ else if (opcode <= DW_LNS_set_epilogue_begin)
{
/* This is a known standard opcode. */
switch (opcode)
@@ -4314,7 +4438,7 @@ define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
puts (gettext (" set prologue end flag"));
break;
- case DW_LNS_set_epilog_begin:
+ case DW_LNS_set_epilogue_begin:
/* Takes no argument. */
puts (gettext (" set epilogue begin flag"));
break;
@@ -4355,13 +4479,76 @@ print_debug_loc_section (Ebl *ebl __attribute__ ((unused)),
GElf_Shdr *shdr,
Dwarf *dbg __attribute__ ((unused)))
{
+ Elf_Data *data = elf_rawdata (scn, NULL);
+
+ if (data == NULL)
+ {
+ error (0, 0, gettext ("cannot get .debug_loc content: %s"),
+ elf_errmsg (-1));
+ return;
+ }
+
printf (gettext ("\
\nDWARF section '%s' at offset %#" PRIx64 ":\n"),
".debug_loc", (uint64_t) shdr->sh_offset);
- // XXX add something
-}
+ size_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+ bool first = true;
+ unsigned char *readp = data->d_buf;
+ while (readp < (unsigned char *) data->d_buf + data->d_size)
+ {
+ ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
+ if (data->d_size - offset < address_size * 2)
+ {
+ printf (" [%6tx] <INVALID DATA>\n", offset);
+ break;
+ }
+
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+ if (address_size == 8)
+ {
+ begin = read_8ubyte_unaligned_inc (dbg, readp);
+ end = read_8ubyte_unaligned_inc (dbg, readp);
+ }
+ else
+ {
+ begin = read_4ubyte_unaligned_inc (dbg, readp);
+ end = read_4ubyte_unaligned_inc (dbg, readp);
+ if (begin == (Dwarf_Addr) (uint32_t) -1)
+ begin = (Dwarf_Addr) -1l;
+ }
+
+ if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
+ printf (" [%6tx] base address %#0*" PRIxMAX "\n", offset,
+ 2 + (int) (address_size * 2), (uintmax_t) end);
+ else if (begin == 0 && end == 0) /* End of list entry. */
+ first = true;
+ else
+ {
+ /* We have a location expression entry. */
+ uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
+
+ if (first) /* First entry in a list. */
+ printf (" [%6tx] %#0*" PRIxMAX "..%#0*" PRIxMAX,
+ offset,
+ 2 + (int) (address_size * 2), (uintmax_t) begin,
+ 2 + (int) (address_size * 2), (uintmax_t) end);
+ else
+ printf (" %#0*" PRIxMAX "..%#0*" PRIxMAX,
+ 2 + (int) (address_size * 2), (uintmax_t) begin,
+ 2 + (int) (address_size * 2), (uintmax_t) end);
+
+ print_ops (dbg, 1, 18 + (address_size * 4),
+ address_size, len, readp);
+
+ first = false;
+ readp += len;
+ }
+ }
+}
struct mac_culist
{
@@ -4662,6 +4849,7 @@ print_debug (Ebl *ebl, GElf_Ehdr *ehdr)
NEW_SECTION (pubnames),
NEW_SECTION (str),
NEW_SECTION (macinfo),
+ NEW_SECTION (ranges),
{ ".eh_frame", section_frame, print_debug_frame_section }
};
const int ndebug_sections = (sizeof (debug_sections)
@@ -4727,7 +4915,8 @@ handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
The variable sized fields are padded to 32- or 64-bits
depending on whether the file is a 32- or 64-bit ELF file.
*/
- size_t align = class == ELFCLASS32 ? 4 : 8;
+ // XXX Which 64-bit archs need 8-byte alignment? x86-64 does not.
+ size_t align = class == ELFCLASS32 ? 4 : 4; // XXX 8;
#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1))
size_t idx = 0;
diff --git a/elfutils/src/strip.c b/elfutils/src/strip.c
index 0502d944..42e13b46 100644
--- a/elfutils/src/strip.c
+++ b/elfutils/src/strip.c
@@ -63,11 +63,15 @@ static const struct argp_option options[] =
{ NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 },
{ NULL, 0, NULL, 0, N_("Output options:"), 0 },
+ { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 },
{ "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 },
+ { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 },
+ { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 },
{ "preserve-dates", 'p', NULL, 0,
N_("Copy modified/access timestamps to the output"), 0 },
{ "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
N_("Remove .comment section"), 0 },
+ { "remove-section", 'R', "SECTION", OPTION_HIDDEN, NULL, 0 },
{ "permissive", OPT_PERMISSIVE, NULL, 0,
N_("Relax a few rules to handle slightly broken ELF files"), 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
@@ -195,8 +199,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
/* Handle program arguments. */
static error_t
-parse_opt (int key, char *arg,
- struct argp_state *state __attribute__ ((unused)))
+parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
@@ -235,7 +238,20 @@ parse_opt (int key, char *arg,
remove_comment = true;
break;
+ case 'R':
+ if (!strcmp (arg, ".comment"))
+ remove_comment = true;
+ else
+ {
+ argp_error (state,
+ gettext ("-R option supports only .comment section"));
+ return EINVAL;
+ }
+ break;
+
case 'g':
+ case 'd':
+ case 'S':
remove_debug = true;
break;
@@ -243,6 +259,9 @@ parse_opt (int key, char *arg,
permissive = true;
break;
+ case 's': /* Ignored for compatibility. */
+ break;
+
default:
return ARGP_ERR_UNKNOWN;
}
@@ -274,7 +293,7 @@ process_file (const char *fname)
}
/* Open the file. */
- int fd = open (fname, O_RDWR);
+ int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY);
if (fd == -1)
{
error (0, errno, gettext ("while opening \"%s\""), fname);
@@ -300,7 +319,8 @@ process_file (const char *fname)
}
/* Now get the ELF descriptor. */
- Elf *elf = elf_begin (fd, ELF_C_RDWR, NULL);
+ Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ,
+ NULL);
int result;
switch (elf_kind (elf))
{
@@ -348,14 +368,10 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
size_t fname_len = strlen (fname) + 1;
char *fullname = alloca (prefix_len + 1 + fname_len);
char *cp = fullname;
- Elf *newelf;
Elf *debugelf = NULL;
char *tmp_debug_fname = NULL;
int result = 0;
- GElf_Ehdr ehdr_mem;
- GElf_Ehdr *ehdr;
size_t shstrndx;
- size_t shnum;
struct shdr_info
{
Elf_Scn *scn;
@@ -441,7 +457,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
}
/* Get the information from the old file. */
- ehdr = gelf_getehdr (elf, &ehdr_mem);
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
if (ehdr == NULL)
INTERNAL_ERROR (fname);
@@ -453,6 +470,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* We now create a new ELF descriptor for the same file. We
construct it almost exactly in the same way with some information
dropped. */
+ Elf *newelf;
if (output_fname != NULL)
newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
else
@@ -472,9 +490,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
{
GElf_Phdr phdr_mem;
- GElf_Phdr *phdr;
-
- phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+ GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
if (phdr == NULL
|| unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
INTERNAL_ERROR (fname);
@@ -498,9 +514,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
{
GElf_Phdr phdr_mem;
- GElf_Phdr *phdr;
-
- phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+ GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
if (phdr == NULL
|| unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
INTERNAL_ERROR (fname);
@@ -508,6 +522,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
}
/* Number of sections. */
+ size_t shnum;
if (unlikely (elf_getshnum (elf, &shnum) < 0))
{
error (0, 0, gettext ("cannot determine number of sections: %s"),
@@ -575,9 +590,6 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
}
else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
{
- Elf32_Word *grpref;
- size_t inner;
-
/* Cross-reference the sections contained in the section
group. */
shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
@@ -585,7 +597,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
INTERNAL_ERROR (fname);
/* XXX Fix for unaligned access. */
- grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
+ Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
+ size_t inner;
for (inner = 1;
inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
++inner)
@@ -634,8 +647,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
*/
for (cnt = 1; cnt < shnum; ++cnt)
/* Check whether the section can be removed. */
- if (SECTION_STRIP_P (ebl, elf, ehdr, &shdr_info[cnt].shdr,
- shdr_info[cnt].name, remove_comment, remove_debug))
+ if (ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr,
+ shdr_info[cnt].name, remove_comment,
+ remove_debug))
{
/* For now assume this section will be removed. */
shdr_info[cnt].idx = 0;
@@ -643,16 +657,14 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
idx = shdr_info[cnt].group_idx;
while (idx != 0)
{
- /* If the references section group is a normal section
- group and has one element remaining, or if it is an
- empty COMDAT section group it is removed. */
- bool is_comdat;
-
/* The section group data is already loaded. */
assert (shdr_info[idx].data != NULL);
- is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
- & GRP_COMDAT) != 0;
+ /* If the references section group is a normal section
+ group and has one element remaining, or if it is an
+ empty COMDAT section group it is removed. */
+ bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
+ & GRP_COMDAT) != 0;
--shdr_info[idx].group_cnt;
if ((!is_comdat && shdr_info[idx].group_cnt == 1)
@@ -698,10 +710,6 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
|| shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
{
- Elf_Data *symdata;
- Elf_Data *xndxdata;
- size_t elsize;
-
/* Make sure the data is loaded. */
if (shdr_info[cnt].data == NULL)
{
@@ -710,7 +718,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (shdr_info[cnt].data == NULL)
INTERNAL_ERROR (fname);
}
- symdata = shdr_info[cnt].data;
+ Elf_Data *symdata = shdr_info[cnt].data;
/* If there is an extended section index table load it
as well. */
@@ -725,11 +733,13 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
INTERNAL_ERROR (fname);
}
- xndxdata = shdr_info[shdr_info[cnt].symtab_idx].data;
+ Elf_Data *xndxdata
+ = shdr_info[shdr_info[cnt].symtab_idx].data;
/* Go through all symbols and make sure the section they
reference is not removed. */
- elsize = gelf_fsize (elf, ELF_T_SYM, 1, ehdr->e_version);
+ size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
+ ehdr->e_version);
for (size_t inner = 0;
inner < shdr_info[cnt].data->d_size / elsize;
@@ -737,15 +747,13 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
{
GElf_Sym sym_mem;
Elf32_Word xndx;
- GElf_Sym *sym;
- size_t scnidx;
-
- sym = gelf_getsymshndx (symdata, xndxdata, inner,
- &sym_mem, &xndx);
+ GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
+ inner, &sym_mem,
+ &xndx);
if (sym == NULL)
INTERNAL_ERROR (fname);
- scnidx = sym->st_shndx;
+ size_t scnidx = sym->st_shndx;
if (scnidx == SHN_UNDEF || scnidx >= shnum
|| (scnidx >= SHN_LORESERVE
&& scnidx <= SHN_HIRESERVE
@@ -808,20 +816,17 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
{
for (cnt = 1; cnt < shnum; ++cnt)
{
- Elf_Data *debugdata;
- GElf_Shdr debugshdr;
- bool discard_section;
-
scn = elf_newscn (debugelf);
if (scn == NULL)
error (EXIT_FAILURE, 0,
gettext ("while generating output file: %s"),
elf_errmsg (-1));
- discard_section = shdr_info[cnt].idx > 0 && cnt != ehdr->e_shstrndx;
+ bool discard_section = (shdr_info[cnt].idx > 0
+ && cnt != ehdr->e_shstrndx);
/* Set the section header in the new file. */
- debugshdr = shdr_info[cnt].shdr;
+ GElf_Shdr debugshdr = shdr_info[cnt].shdr;
if (discard_section)
debugshdr.sh_type = SHT_NOBITS;
@@ -838,7 +843,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
}
/* Set the data. This is done by copying from the old file. */
- debugdata = elf_newdata (scn);
+ Elf_Data *debugdata = elf_newdata (scn);
if (debugdata == NULL)
INTERNAL_ERROR (fname);
@@ -909,9 +914,6 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Create the reference to the file with the debug info. */
if (debug_fname != NULL)
{
- char *debug_basename;
- off_t crc_offset;
-
/* Add the section header string table section name. */
shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15);
shdr_info[cnt].idx = idx++;
@@ -942,8 +944,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
elf_errmsg (-1));
- debug_basename = basename (debug_fname_embed ?: debug_fname);
- crc_offset = strlen (debug_basename) + 1;
+ char *debug_basename = basename (debug_fname_embed ?: debug_fname);
+ off_t crc_offset = strlen (debug_basename) + 1;
/* Align to 4 byte boundary */
crc_offset = ((crc_offset - 1) & ~3) + 4;
diff --git a/elfutils/src/ylwrap b/elfutils/src/ylwrap
index e8abf827..e8abf827 100755..100644
--- a/elfutils/src/ylwrap
+++ b/elfutils/src/ylwrap
diff --git a/elfutils/tests/ChangeLog b/elfutils/tests/ChangeLog
index b1918d8f..176f6b23 100644
--- a/elfutils/tests/ChangeLog
+++ b/elfutils/tests/ChangeLog
@@ -1,8 +1,115 @@
+2005-08-24 Ulrich Drepper <drepper@redhat.com>
+
+ * run-line2addr.sh: Remove testfile23 in the end.
+
+ * Makefile.am [BUILD_STATIC] (libdw): Add $(libelf) and $(libebl).
+ [MUDFLAP] (AM_LDFLAGS): Define to find libebl modules.
+
+2005-08-22 Roland McGrath <roland@redhat.com>
+
+ * run-line2addr.sh: Add a case.
+ * testfile23.bz2: New data file.
+ * Makefile.am (EXTRA_DIST): Add it.
+
+2005-08-18 Roland McGrath <roland@redhat.com>
+
+ * run-addrscopes.sh: New file.
+ * testfile22.bz2: New data file.
+ * Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+ * addrscopes.c: New file.
+ * Makefile.am (noinst_PROGRAMS): Add it.
+ (addrscopes_LDADD): New variable.
+
+2005-08-15 Ulrich Drepper <drepper@redhat.com>
+
+ * run-elflint-self.sh: Don't run test if the file doesn't exist.
+
+2005-08-15 Roland McGrath <roland@redhat.com>
+
+ * dwflmodtest.c (print_instance, print_inline): New functions.
+ (print_func): Call print_inline.
+ (options, parse_opt): Grok -i/--inlines.
+
+2005-08-07 Roland McGrath <roland@redhat.com>
+
+ * dwflmodtest.c: Print function details only if -f flag is given.
+
+2005-08-06 Ulrich Drepper <drepper@redhat.com>
+
+ * run-elflint-self.sh: New file.
+ * Makefile.am (TESTS): Add run-elflint-self.sh.
+ (EXTRA_DIST): Likewise.
+
+ * Makefile.am: Link with statis libs if BUILD_STATIC.
+ (dwflmodtest_LDADD): Also link with -ldl.
+
+2005-08-02 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am: Add -ldl to asm_tst[1-9]_LDASS.
+ * asm-tst1.c: Adjust for new asm_begin interface. Open backend
+ library first.
+ * asm-tst2.c: Likewise.
+ * asm-tst3.c: Likewise.
+ * asm-tst4.c: Likewise.
+ * asm-tst5.c: Likewise.
+ * asm-tst6.c: Likewise.
+ * asm-tst7.c: Likewise.
+ * asm-tst8.c: Likewise.
+ * asm-tst9.c: Likewise.
+
+ * msg_tst.c: Add new error message.
+
+2005-07-28 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am (dwflmodtest_LDADD): Add $(libebl).
+
+2005-06-01 Roland McGrath <roland@redhat.com>
+
+ * line2addr.c: Rewritten using libdwfl.
+ * run-line2addr.sh: Update test for changed arguments.
+ * Makefile.am (INCLUDES): Add libdwfl source directory to path.
+ (libdwfl): New variable.
+ (line2addr_LDADD): Use it.
+
+2005-07-28 Roland McGrath <roland@redhat.com>
+
+ * dwflmodtest.c: New file, moved from ../libdwfl/ptest.c to here.
+ * Makefile.am (noinst_PROGRAMS): Add dwflmodtest.
+ (dwflmodtest_LDADD): New variable.
+ (INCLUDES): Add -I$(top_srcdir)/libdwfl here.
+
+2005-07-21 Ulrich Drepper <drepper@redhat.com>
+
+ * testfile18.bz2: New file.
+ * run-elflint-test.sh: New file.
+ * Makefile.am (TESTS): Add run-elflint-test.sh.
+ (EXTRA_DIST): Add run-elflint-test.sh and testfile18.bz2.
+
+2005-05-24 Ulrich Drepper <drepper@redhat.com>
+
+ * get-files.c (main): Use correct format specifier.
+
+2005-05-21 Ulrich Drepper <drepper@redhat.com>
+
+ * Makefile.am: Add -Wextra to CFLAGS.
+ * get-files.c: Remove warning this produced.
+ * get-pubnames.c: Likewise.
+ * newfile.c: Likewise.
+ * newscn.c: Likewise.
+ * scnnames.c: Likewise.
+ * showptable.c: Likewise.
+ * test-nlist.c: Likewise.
+ * update1.c: Likewise.
+ * update2.c: Likewise.
+ * update3.c: Likewise.
+ * update4.c: Likewise.
+
2005-05-08 Ulrich Drepper <drepper@redhat.com>
* run-line2addr.sh: Remove testfile14 at the end.
- * run-strip-test.sh: Remove deubinfo test input file as well.
+ * run-strip-test.sh: Remove debuginfo test input file as well.
* Makefile.am (EXTRA_DIST): Newly added files incorrectly used
.bz, not .bz2.
diff --git a/elfutils/tests/Makefile.am b/elfutils/tests/Makefile.am
index 769a2314..b4cc1b04 100644
--- a/elfutils/tests/Makefile.am
+++ b/elfutils/tests/Makefile.am
@@ -14,24 +14,26 @@
##
DEFS = -DHAVE_CONFIG_H -D_GNU_SOURCE
if MUDFLAP
-AM_CFLAGS = -Wall -Werror -std=gnu99 -fmudflap\
+AM_CFLAGS = -Wall -Werror -Wextra -std=gnu99 -fmudflap\
$(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2)
+AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libebl
else
-AM_CFLAGS = -Wall -Werror -std=gnu99 \
+AM_CFLAGS = -Wall -Werror -Wextra -std=gnu99 \
$(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2)
AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../libebl:\$$ORIGIN/../libelf
endif
INCLUDES = -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
+ -I$(top_srcdir)/libdwfl \
-I$(top_srcdir)/libebl -I$(top_srcdir)/libelf \
-I$(top_srcdir)/lib -I..
noinst_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
showptable update1 update2 update3 update4 test-nlist \
show-die-info get-files get-lines get-pubnames \
- get-aranges allfcts line2addr \
+ get-aranges allfcts line2addr addrscopes \
show-abbrev hash asm-tst1 asm-tst2 asm-tst3 \
asm-tst4 asm-tst5 asm-tst6 asm-tst7 asm-tst8 asm-tst9 \
- msg_tst newscn ecp
+ msg_tst newscn ecp dwflmodtest
# get-ciefde
TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
@@ -42,7 +44,10 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
asm-tst3 asm-tst4 asm-tst5 asm-tst6 asm-tst7 asm-tst8 asm-tst9 \
msg_tst newscn run-strip-test.sh run-strip-test2.sh \
run-strip-test3.sh run-strip-test4.sh run-strip-test5.sh \
- run-strip-test6.sh run-ecp-test.sh run-ecp-test2.sh
+ run-strip-test6.sh run-ecp-test.sh run-ecp-test2.sh \
+ run-elflint-test.sh run-elflint-self.sh run-ranlib-test.sh \
+ run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \
+ run-addrscopes.sh
# run-show-ciefde.sh
EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
@@ -54,17 +59,28 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
testfile5.bz2 testfile6.bz2 testfile7.bz2 testfile8.bz2 \
testfile9.bz2 testfile10.bz2 testfile11.bz2 testfile12.bz2 \
testfile13.bz2 run-strip-test3.sh run-allfcts.sh \
- run-line2addr.sh testfile14.bz2 \
+ run-line2addr.sh run-elflint-test.sh testfile14.bz2 \
run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \
+ run-elflint-self.sh run-ranlib-test.sh run-ranlib-test2.sh \
+ run-ranlib-test3.sh run-ranlib-test4.sh \
+ run-addrscopes.sh \
testfile15.bz2 testfile15.debug.bz2 \
testfile16.bz2 testfile16.debug.bz2 \
- testfile17.bz2 testfile17.debug.bz2
+ testfile17.bz2 testfile17.debug.bz2 \
+ testfile18.bz2 testfile19.bz2 testfile19.index.bz2 \
+ testfile20.bz2 testfile20.index.bz2 \
+ testfile21.bz2 testfile21.index.bz2 \
+ testfile22.bz2 testfile23.bz2
if MUDFLAP
-libdw = ../libdw/libdw.a
+static_build=yes
+libmudflap = -lmudflap
+endif
+
+if BUILD_STATIC
+libdw = ../libdw/libdw.a $(libelf) $(libebl)
libelf = ../libelf/libelf.a
libasm = ../libasm/libasm.a
-libmudflap = -lmudflap
else
libdw = ../libdw/libdw.so
libelf = ../libelf/libelf.so
@@ -96,16 +112,18 @@ get_files_LDADD = $(libdw) $(libelf) $(libmudflap)
get_aranges_LDADD = $(libdw) $(libelf) $(libmudflap)
allfcts_LDADD = $(libdw) $(libelf) $(libmudflap)
line2addr_no_Wformat = yes
-line2addr_LDADD = $(libdw) $(libelf) $(libmudflap)
+line2addr_LDADD = $(libdw) $(libmudflap)
+addrscopes_LDADD = $(libdw) $(libmudflap)
#show_ciefde_LDADD = ../libdwarf/libdwarf.so $(libelf) $(libmudflap)
-asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst2_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst3_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst4_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst5_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst6_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
+asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst2_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst3_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst4_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst5_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst6_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+dwflmodtest_LDADD = $(libdw) $(libebl) $(libelf) $(libmudflap) -ldl
CLEANFILES = xxx
diff --git a/elfutils/tests/Makefile.in b/elfutils/tests/Makefile.in
index 7c661ec1..81e864b1 100644
--- a/elfutils/tests/Makefile.in
+++ b/elfutils/tests/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -14,8 +14,6 @@
@SET_MAKE@
-SOURCES = allfcts.c arextract.c arsymtest.c asm-tst1.c asm-tst2.c asm-tst3.c asm-tst4.c asm-tst5.c asm-tst6.c asm-tst7.c asm-tst8.c asm-tst9.c ecp.c get-aranges.c get-files.c get-lines.c get-pubnames.c hash.c line2addr.c msg_tst.c newfile.c newscn.c saridx.c scnnames.c sectiondump.c show-abbrev.c show-die-info.c showptable.c test-nlist.c update1.c update2.c update3.c update4.c
-
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -44,12 +42,12 @@ noinst_PROGRAMS = arextract$(EXEEXT) arsymtest$(EXEEXT) \
update2$(EXEEXT) update3$(EXEEXT) update4$(EXEEXT) \
test-nlist$(EXEEXT) show-die-info$(EXEEXT) get-files$(EXEEXT) \
get-lines$(EXEEXT) get-pubnames$(EXEEXT) get-aranges$(EXEEXT) \
- allfcts$(EXEEXT) line2addr$(EXEEXT) show-abbrev$(EXEEXT) \
- hash$(EXEEXT) asm-tst1$(EXEEXT) asm-tst2$(EXEEXT) \
- asm-tst3$(EXEEXT) asm-tst4$(EXEEXT) asm-tst5$(EXEEXT) \
- asm-tst6$(EXEEXT) asm-tst7$(EXEEXT) asm-tst8$(EXEEXT) \
- asm-tst9$(EXEEXT) msg_tst$(EXEEXT) newscn$(EXEEXT) \
- ecp$(EXEEXT)
+ allfcts$(EXEEXT) line2addr$(EXEEXT) addrscopes$(EXEEXT) \
+ show-abbrev$(EXEEXT) hash$(EXEEXT) asm-tst1$(EXEEXT) \
+ asm-tst2$(EXEEXT) asm-tst3$(EXEEXT) asm-tst4$(EXEEXT) \
+ asm-tst5$(EXEEXT) asm-tst6$(EXEEXT) asm-tst7$(EXEEXT) \
+ asm-tst8$(EXEEXT) asm-tst9$(EXEEXT) msg_tst$(EXEEXT) \
+ newscn$(EXEEXT) ecp$(EXEEXT) dwflmodtest$(EXEEXT)
subdir = tests
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -61,132 +59,139 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(noinst_PROGRAMS)
+addrscopes_SOURCES = addrscopes.c
+addrscopes_OBJECTS = addrscopes.$(OBJEXT)
+@BUILD_STATIC_FALSE@am__DEPENDENCIES_1 = ../libelf/libelf.so
+@BUILD_STATIC_TRUE@am__DEPENDENCIES_1 = ../libelf/libelf.a
+am__DEPENDENCIES_2 = ../libebl/libebl.a
+@BUILD_STATIC_FALSE@am__DEPENDENCIES_3 = ../libdw/libdw.so
+@BUILD_STATIC_TRUE@am__DEPENDENCIES_3 = ../libdw/libdw.a \
+@BUILD_STATIC_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+am__DEPENDENCIES_4 =
+addrscopes_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_4)
allfcts_SOURCES = allfcts.c
allfcts_OBJECTS = allfcts.$(OBJEXT)
-@MUDFLAP_FALSE@am__DEPENDENCIES_1 = ../libdw/libdw.so
-@MUDFLAP_TRUE@am__DEPENDENCIES_1 = ../libdw/libdw.a
-@MUDFLAP_FALSE@am__DEPENDENCIES_2 = ../libelf/libelf.so
-@MUDFLAP_TRUE@am__DEPENDENCIES_2 = ../libelf/libelf.a
-am__DEPENDENCIES_3 =
-allfcts_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+allfcts_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
arextract_SOURCES = arextract.c
arextract_OBJECTS = arextract.$(OBJEXT)
-arextract_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+arextract_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
arsymtest_SOURCES = arsymtest.c
arsymtest_OBJECTS = arsymtest.$(OBJEXT)
-arsymtest_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+arsymtest_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst1_SOURCES = asm-tst1.c
asm_tst1_OBJECTS = asm-tst1.$(OBJEXT)
-@MUDFLAP_FALSE@am__DEPENDENCIES_4 = ../libasm/libasm.so
-@MUDFLAP_TRUE@am__DEPENDENCIES_4 = ../libasm/libasm.a
-am__DEPENDENCIES_5 = ../libebl/libebl.a
-asm_tst1_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+@BUILD_STATIC_FALSE@am__DEPENDENCIES_5 = ../libasm/libasm.so
+@BUILD_STATIC_TRUE@am__DEPENDENCIES_5 = ../libasm/libasm.a
+asm_tst1_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst2_SOURCES = asm-tst2.c
asm_tst2_OBJECTS = asm-tst2.$(OBJEXT)
-asm_tst2_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst2_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst3_SOURCES = asm-tst3.c
asm_tst3_OBJECTS = asm-tst3.$(OBJEXT)
-asm_tst3_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst3_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst4_SOURCES = asm-tst4.c
asm_tst4_OBJECTS = asm-tst4.$(OBJEXT)
-asm_tst4_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst4_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst5_SOURCES = asm-tst5.c
asm_tst5_OBJECTS = asm-tst5.$(OBJEXT)
-asm_tst5_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst5_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst6_SOURCES = asm-tst6.c
asm_tst6_OBJECTS = asm-tst6.$(OBJEXT)
-asm_tst6_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst6_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst7_SOURCES = asm-tst7.c
asm_tst7_OBJECTS = asm-tst7.$(OBJEXT)
-asm_tst7_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst7_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst8_SOURCES = asm-tst8.c
asm_tst8_OBJECTS = asm-tst8.$(OBJEXT)
-asm_tst8_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst8_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
asm_tst9_SOURCES = asm-tst9.c
asm_tst9_OBJECTS = asm-tst9.$(OBJEXT)
-asm_tst9_DEPENDENCIES = $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+asm_tst9_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
+dwflmodtest_SOURCES = dwflmodtest.c
+dwflmodtest_OBJECTS = dwflmodtest.$(OBJEXT)
+dwflmodtest_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
ecp_SOURCES = ecp.c
ecp_OBJECTS = ecp.$(OBJEXT)
-ecp_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+ecp_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
get_aranges_SOURCES = get-aranges.c
get_aranges_OBJECTS = get-aranges.$(OBJEXT)
-get_aranges_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+get_aranges_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
get_files_SOURCES = get-files.c
get_files_OBJECTS = get-files.$(OBJEXT)
-get_files_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+get_files_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
get_lines_SOURCES = get-lines.c
get_lines_OBJECTS = get-lines.$(OBJEXT)
-get_lines_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+get_lines_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
get_pubnames_SOURCES = get-pubnames.c
get_pubnames_OBJECTS = get-pubnames.$(OBJEXT)
-get_pubnames_DEPENDENCIES = $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+get_pubnames_DEPENDENCIES = $(am__DEPENDENCIES_3) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
hash_SOURCES = hash.c
hash_OBJECTS = hash.$(OBJEXT)
-hash_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+hash_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
line2addr_SOURCES = line2addr.c
line2addr_OBJECTS = line2addr.$(OBJEXT)
-line2addr_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+line2addr_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_4)
msg_tst_SOURCES = msg_tst.c
msg_tst_OBJECTS = msg_tst.$(OBJEXT)
-msg_tst_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+msg_tst_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
newfile_SOURCES = newfile.c
newfile_OBJECTS = newfile.$(OBJEXT)
-newfile_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+newfile_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
newscn_SOURCES = newscn.c
newscn_OBJECTS = newscn.$(OBJEXT)
-newscn_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+newscn_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
saridx_SOURCES = saridx.c
saridx_OBJECTS = saridx.$(OBJEXT)
-saridx_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+saridx_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
scnnames_SOURCES = scnnames.c
scnnames_OBJECTS = scnnames.$(OBJEXT)
-scnnames_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+scnnames_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
sectiondump_SOURCES = sectiondump.c
sectiondump_OBJECTS = sectiondump.$(OBJEXT)
-sectiondump_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+sectiondump_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
show_abbrev_SOURCES = show-abbrev.c
show_abbrev_OBJECTS = show-abbrev.$(OBJEXT)
-show_abbrev_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+show_abbrev_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
show_die_info_SOURCES = show-die-info.c
show_die_info_OBJECTS = show-die-info.$(OBJEXT)
-show_die_info_DEPENDENCIES = $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+show_die_info_DEPENDENCIES = $(am__DEPENDENCIES_3) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
showptable_SOURCES = showptable.c
showptable_OBJECTS = showptable.$(OBJEXT)
-showptable_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+showptable_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
test_nlist_SOURCES = test-nlist.c
test_nlist_OBJECTS = test-nlist.$(OBJEXT)
-test_nlist_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+test_nlist_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
update1_SOURCES = update1.c
update1_OBJECTS = update1.$(OBJEXT)
-update1_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+update1_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
update2_SOURCES = update2.c
update2_OBJECTS = update2.$(OBJEXT)
-update2_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
+update2_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4)
update3_SOURCES = update3.c
update3_OBJECTS = update3.$(OBJEXT)
-update3_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+update3_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
update4_SOURCES = update4.c
update4_OBJECTS = update4.$(OBJEXT)
-update4_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_3)
+update4_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_4)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
@@ -194,20 +199,21 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = allfcts.c arextract.c arsymtest.c asm-tst1.c asm-tst2.c \
- asm-tst3.c asm-tst4.c asm-tst5.c asm-tst6.c asm-tst7.c \
- asm-tst8.c asm-tst9.c ecp.c get-aranges.c get-files.c \
- get-lines.c get-pubnames.c hash.c line2addr.c msg_tst.c \
- newfile.c newscn.c saridx.c scnnames.c sectiondump.c \
- show-abbrev.c show-die-info.c showptable.c test-nlist.c \
- update1.c update2.c update3.c update4.c
-DIST_SOURCES = allfcts.c arextract.c arsymtest.c asm-tst1.c asm-tst2.c \
- asm-tst3.c asm-tst4.c asm-tst5.c asm-tst6.c asm-tst7.c \
- asm-tst8.c asm-tst9.c ecp.c get-aranges.c get-files.c \
- get-lines.c get-pubnames.c hash.c line2addr.c msg_tst.c \
- newfile.c newscn.c saridx.c scnnames.c sectiondump.c \
- show-abbrev.c show-die-info.c showptable.c test-nlist.c \
- update1.c update2.c update3.c update4.c
+SOURCES = addrscopes.c allfcts.c arextract.c arsymtest.c asm-tst1.c \
+ asm-tst2.c asm-tst3.c asm-tst4.c asm-tst5.c asm-tst6.c \
+ asm-tst7.c asm-tst8.c asm-tst9.c dwflmodtest.c ecp.c \
+ get-aranges.c get-files.c get-lines.c get-pubnames.c hash.c \
+ line2addr.c msg_tst.c newfile.c newscn.c saridx.c scnnames.c \
+ sectiondump.c show-abbrev.c show-die-info.c showptable.c \
+ test-nlist.c update1.c update2.c update3.c update4.c
+DIST_SOURCES = addrscopes.c allfcts.c arextract.c arsymtest.c \
+ asm-tst1.c asm-tst2.c asm-tst3.c asm-tst4.c asm-tst5.c \
+ asm-tst6.c asm-tst7.c asm-tst8.c asm-tst9.c dwflmodtest.c \
+ ecp.c get-aranges.c get-files.c get-lines.c get-pubnames.c \
+ hash.c line2addr.c msg_tst.c newfile.c newscn.c saridx.c \
+ scnnames.c sectiondump.c show-abbrev.c show-die-info.c \
+ showptable.c test-nlist.c update1.c update2.c update3.c \
+ update4.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -219,6 +225,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BUILD_STATIC_FALSE = @BUILD_STATIC_FALSE@
+BUILD_STATIC_TRUE = @BUILD_STATIC_TRUE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -232,6 +240,8 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
GMSGFMT = @GMSGFMT@
+GPROF_FALSE = @GPROF_FALSE@
+GPROF_TRUE = @GPROF_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -240,12 +250,14 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCALEDIR = @LOCALEDIR@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
+MODVERSION = @MODVERSION@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MUDFLAP_FALSE = @MUDFLAP_FALSE@
@@ -307,14 +319,16 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Werror -std=gnu99 \
+@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Werror -Wextra -std=gnu99 \
@MUDFLAP_FALSE@ $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2)
-@MUDFLAP_TRUE@AM_CFLAGS = -Wall -Werror -std=gnu99 -fmudflap\
+@MUDFLAP_TRUE@AM_CFLAGS = -Wall -Werror -Wextra -std=gnu99 -fmudflap\
@MUDFLAP_TRUE@ $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2)
@MUDFLAP_FALSE@AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../libebl:\$$ORIGIN/../libelf
+@MUDFLAP_TRUE@AM_LDFLAGS = -Wl,-rpath,\$$ORIGIN/../libebl
INCLUDES = -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
+ -I$(top_srcdir)/libdwfl \
-I$(top_srcdir)/libebl -I$(top_srcdir)/libelf \
-I$(top_srcdir)/lib -I..
@@ -327,7 +341,10 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
asm-tst3 asm-tst4 asm-tst5 asm-tst6 asm-tst7 asm-tst8 asm-tst9 \
msg_tst newscn run-strip-test.sh run-strip-test2.sh \
run-strip-test3.sh run-strip-test4.sh run-strip-test5.sh \
- run-strip-test6.sh run-ecp-test.sh run-ecp-test2.sh
+ run-strip-test6.sh run-ecp-test.sh run-ecp-test2.sh \
+ run-elflint-test.sh run-elflint-self.sh run-ranlib-test.sh \
+ run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \
+ run-addrscopes.sh
# run-show-ciefde.sh
EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
@@ -339,19 +356,27 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
testfile5.bz2 testfile6.bz2 testfile7.bz2 testfile8.bz2 \
testfile9.bz2 testfile10.bz2 testfile11.bz2 testfile12.bz2 \
testfile13.bz2 run-strip-test3.sh run-allfcts.sh \
- run-line2addr.sh testfile14.bz2 \
+ run-line2addr.sh run-elflint-test.sh testfile14.bz2 \
run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \
+ run-elflint-self.sh run-ranlib-test.sh run-ranlib-test2.sh \
+ run-ranlib-test3.sh run-ranlib-test4.sh \
+ run-addrscopes.sh \
testfile15.bz2 testfile15.debug.bz2 \
testfile16.bz2 testfile16.debug.bz2 \
- testfile17.bz2 testfile17.debug.bz2
-
-@MUDFLAP_FALSE@libdw = ../libdw/libdw.so
-@MUDFLAP_TRUE@libdw = ../libdw/libdw.a
-@MUDFLAP_FALSE@libelf = ../libelf/libelf.so
-@MUDFLAP_TRUE@libelf = ../libelf/libelf.a
-@MUDFLAP_FALSE@libasm = ../libasm/libasm.so
-@MUDFLAP_TRUE@libasm = ../libasm/libasm.a
+ testfile17.bz2 testfile17.debug.bz2 \
+ testfile18.bz2 testfile19.bz2 testfile19.index.bz2 \
+ testfile20.bz2 testfile20.index.bz2 \
+ testfile21.bz2 testfile21.index.bz2 \
+ testfile22.bz2 testfile23.bz2
+
+@MUDFLAP_TRUE@static_build = yes
@MUDFLAP_TRUE@libmudflap = -lmudflap
+@BUILD_STATIC_FALSE@libdw = ../libdw/libdw.so
+@BUILD_STATIC_TRUE@libdw = ../libdw/libdw.a $(libelf) $(libebl)
+@BUILD_STATIC_FALSE@libelf = ../libelf/libelf.so
+@BUILD_STATIC_TRUE@libelf = ../libelf/libelf.a
+@BUILD_STATIC_FALSE@libasm = ../libasm/libasm.so
+@BUILD_STATIC_TRUE@libasm = ../libasm/libasm.a
libebl = ../libebl/libebl.a
arextract_LDADD = $(libelf) $(libmudflap)
arsymtest_LDADD = $(libelf) $(libmudflap)
@@ -377,17 +402,19 @@ get_files_LDADD = $(libdw) $(libelf) $(libmudflap)
get_aranges_LDADD = $(libdw) $(libelf) $(libmudflap)
allfcts_LDADD = $(libdw) $(libelf) $(libmudflap)
line2addr_no_Wformat = yes
-line2addr_LDADD = $(libdw) $(libelf) $(libmudflap)
+line2addr_LDADD = $(libdw) $(libmudflap)
+addrscopes_LDADD = $(libdw) $(libmudflap)
#show_ciefde_LDADD = ../libdwarf/libdwarf.so $(libelf) $(libmudflap)
-asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst2_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst3_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst4_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst5_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst6_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
-asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap)
+asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst2_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst3_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst4_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst5_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst6_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl
+dwflmodtest_LDADD = $(libdw) $(libebl) $(libelf) $(libmudflap) -ldl
CLEANFILES = xxx
all: all-am
@@ -425,6 +452,9 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+addrscopes$(EXEEXT): $(addrscopes_OBJECTS) $(addrscopes_DEPENDENCIES)
+ @rm -f addrscopes$(EXEEXT)
+ $(LINK) $(addrscopes_LDFLAGS) $(addrscopes_OBJECTS) $(addrscopes_LDADD) $(LIBS)
allfcts$(EXEEXT): $(allfcts_OBJECTS) $(allfcts_DEPENDENCIES)
@rm -f allfcts$(EXEEXT)
$(LINK) $(allfcts_LDFLAGS) $(allfcts_OBJECTS) $(allfcts_LDADD) $(LIBS)
@@ -461,6 +491,9 @@ asm-tst8$(EXEEXT): $(asm_tst8_OBJECTS) $(asm_tst8_DEPENDENCIES)
asm-tst9$(EXEEXT): $(asm_tst9_OBJECTS) $(asm_tst9_DEPENDENCIES)
@rm -f asm-tst9$(EXEEXT)
$(LINK) $(asm_tst9_LDFLAGS) $(asm_tst9_OBJECTS) $(asm_tst9_LDADD) $(LIBS)
+dwflmodtest$(EXEEXT): $(dwflmodtest_OBJECTS) $(dwflmodtest_DEPENDENCIES)
+ @rm -f dwflmodtest$(EXEEXT)
+ $(LINK) $(dwflmodtest_LDFLAGS) $(dwflmodtest_OBJECTS) $(dwflmodtest_LDADD) $(LIBS)
ecp$(EXEEXT): $(ecp_OBJECTS) $(ecp_DEPENDENCIES)
@rm -f ecp$(EXEEXT)
$(LINK) $(ecp_LDFLAGS) $(ecp_OBJECTS) $(ecp_LDADD) $(LIBS)
@@ -531,6 +564,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addrscopes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allfcts.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arextract.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arsymtest.Po@am__quote@
@@ -543,6 +577,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst7.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst8.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst9.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwflmodtest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-aranges.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-files.Po@am__quote@
diff --git a/elfutils/tests/addrscopes.c b/elfutils/tests/addrscopes.c
new file mode 100644
index 00000000..4ef00648
--- /dev/null
+++ b/elfutils/tests/addrscopes.c
@@ -0,0 +1,194 @@
+/* Test program for dwarf_getscopes.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <libdwfl.h>
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+
+
+static void
+paddr (const char *prefix, Dwarf_Addr addr, Dwfl_Line *line)
+{
+ const char *src;
+ int lineno, linecol;
+ if (line != NULL
+ && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
+ NULL, NULL)) != NULL)
+ {
+ if (linecol != 0)
+ printf ("%s%#" PRIx64 " (%s:%d:%d)",
+ prefix, addr, src, lineno, linecol);
+ else
+ printf ("%s%#" PRIx64 " (%s:%d)",
+ prefix, addr, src, lineno);
+ }
+ else
+ printf ("%s%#" PRIx64, prefix, addr);
+}
+
+static const char *
+dwarf_diename_integrate (Dwarf_Die *die)
+{
+ Dwarf_Attribute attr_mem;
+ return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
+}
+
+static void
+print_vars (unsigned int indent, Dwarf_Die *die)
+{
+ Dwarf_Die child;
+ if (dwarf_child (die, &child) == 0)
+ do
+ switch (dwarf_tag (&child))
+ {
+ case DW_TAG_variable:
+ case DW_TAG_formal_parameter:
+ printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "",
+ dwarf_diename_integrate (&child),
+ (uint64_t) dwarf_dieoffset (&child));
+ break;
+ default:
+ break;
+ }
+ while (dwarf_siblingof (&child, &child) == 0);
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Die origin;
+ if (dwarf_hasattr (die, DW_AT_abstract_origin)
+ && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem),
+ &origin) != NULL
+ && dwarf_child (&origin, &child) == 0)
+ do
+ switch (dwarf_tag (&child))
+ {
+ case DW_TAG_variable:
+ case DW_TAG_formal_parameter:
+ printf ("%*s%s (abstract)\n", indent, "",
+ dwarf_diename_integrate (&child));
+ break;
+ default:
+ break;
+ }
+ while (dwarf_siblingof (&child, &child) == 0);
+}
+
+
+#define INDENT 4
+
+static void
+handle_address (GElf_Addr pc, Dwfl *dwfl)
+{
+ Dwarf_Addr cubias;
+ Dwarf_Die *cudie = dwfl_addrdie (dwfl, pc, &cubias);
+ if (cudie == NULL)
+ error (EXIT_FAILURE, 0, "dwfl_addrdie: %s", dwfl_errmsg (-1));
+
+ Dwarf_Die *scopes;
+ int n = dwarf_getscopes (cudie, pc - cubias, &scopes);
+ if (n < 0)
+ error (EXIT_FAILURE, 0, "dwarf_getscopes: %s", dwarf_errmsg (-1));
+ else if (n == 0)
+ printf ("%#" PRIx64 ": not in any scope\n", pc);
+ else
+ {
+ printf ("%#" PRIx64 ":\n", pc);
+ unsigned int indent = 0;
+ while (n-- > 0)
+ {
+ Dwarf_Die *const die = &scopes[n];
+
+ indent += INDENT;
+ printf ("%*s%s (%#x)", indent, "",
+ dwarf_diename_integrate (die) ?: "<unnamed>",
+ dwarf_tag (die));
+
+ Dwarf_Addr lowpc, highpc;
+ if (dwarf_lowpc (die, &lowpc) == 0
+ && dwarf_highpc (die, &highpc) == 0)
+ {
+ Dwfl_Line *loline = dwfl_getsrc (dwfl, lowpc);
+ Dwfl_Line *hiline = dwfl_getsrc (dwfl, highpc);
+ paddr (": ", lowpc, loline);
+ if (highpc != lowpc)
+ paddr (" .. ", lowpc, hiline == loline ? NULL : hiline);
+ }
+ puts ("");
+
+ print_vars (indent + INDENT, die);
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int remaining;
+
+ /* Set locale. */
+ (void) setlocale (LC_ALL, "");
+
+ Dwfl *dwfl = NULL;
+ (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
+ assert (dwfl != NULL);
+
+ int result = 0;
+
+ /* Now handle the addresses. In case none are given on the command
+ line, read from stdin. */
+ if (remaining == argc)
+ {
+ /* We use no threads here which can interfere with handling a stream. */
+ (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+
+ char *buf = NULL;
+ size_t len = 0;
+ while (!feof_unlocked (stdin))
+ {
+ 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;
+ }
+
+ free (buf);
+ }
+ else
+ {
+ do
+ {
+ char *endp;
+ uintmax_t addr = strtoumax (argv[remaining], &endp, 0);
+ if (endp != argv[remaining])
+ handle_address (addr, dwfl);
+ else
+ result = 1;
+ }
+ while (++remaining < argc);
+ }
+
+ return result;
+}
diff --git a/elfutils/tests/asm-tst1.c b/elfutils/tests/asm-tst1.c
index b76930d0..cfaae345 100644
--- a/elfutils/tests/asm-tst1.c
+++ b/elfutils/tests/asm-tst1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -66,7 +66,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -235,5 +242,7 @@ main (void)
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst2.c b/elfutils/tests/asm-tst2.c
index a309976d..b9a1037f 100644
--- a/elfutils/tests/asm-tst2.c
+++ b/elfutils/tests/asm-tst2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -65,7 +65,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -257,5 +264,7 @@ main (void)
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst3.c b/elfutils/tests/asm-tst3.c
index fb79ea78..155613c5 100644
--- a/elfutils/tests/asm-tst3.c
+++ b/elfutils/tests/asm-tst3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -57,7 +57,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -318,5 +325,7 @@ main (void)
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst4.c b/elfutils/tests/asm-tst4.c
index 29d6485d..50c3c5a5 100644
--- a/elfutils/tests/asm-tst4.c
+++ b/elfutils/tests/asm-tst4.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Red Hat, Inc.
+/* Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -33,7 +33,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -84,5 +91,7 @@ env LD_LIBRARY_PATH=../libelf ../src/elflint -q asm-tst4-out.o"));
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst5.c b/elfutils/tests/asm-tst5.c
index 4f761aed..e5881a53 100644
--- a/elfutils/tests/asm-tst5.c
+++ b/elfutils/tests/asm-tst5.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Red Hat, Inc.
+/* Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -35,7 +35,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -96,5 +103,7 @@ env LD_LIBRARY_PATH=../libelf ../src/elflint -q asm-tst5-out.o"));
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst6.c b/elfutils/tests/asm-tst6.c
index ece69bc2..5ceded65 100644
--- a/elfutils/tests/asm-tst6.c
+++ b/elfutils/tests/asm-tst6.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Red Hat, Inc.
+/* Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -33,7 +33,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -130,5 +137,7 @@ env LD_LIBRARY_PATH=../libelf ../src/elflint -q asm-tst6-out.o"));
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst7.c b/elfutils/tests/asm-tst7.c
index ebd45594..5c94d895 100644
--- a/elfutils/tests/asm-tst7.c
+++ b/elfutils/tests/asm-tst7.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -33,7 +33,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -160,5 +167,7 @@ main (void)
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst8.c b/elfutils/tests/asm-tst8.c
index 6ce7c9c0..cfe53fca 100644
--- a/elfutils/tests/asm-tst8.c
+++ b/elfutils/tests/asm-tst8.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -33,7 +33,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -168,5 +175,7 @@ main (void)
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/asm-tst9.c b/elfutils/tests/asm-tst9.c
index 28bb4787..1f03d8d7 100644
--- a/elfutils/tests/asm-tst9.c
+++ b/elfutils/tests/asm-tst9.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -85,7 +85,14 @@ main (void)
elf_version (EV_CURRENT);
- ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
+ Ebl *ebl = ebl_openbackend_machine (EM_386);
+ if (ebl == NULL)
+ {
+ puts ("cannot open backend library");
+ return 1;
+ }
+
+ ctx = asm_begin (fname, ebl, false);
if (ctx == NULL)
{
printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
@@ -314,5 +321,7 @@ main (void)
/* We don't need the file anymore. */
unlink (fname);
+ ebl_closebackend (ebl);
+
return result;
}
diff --git a/elfutils/tests/dwflmodtest.c b/elfutils/tests/dwflmodtest.c
new file mode 100644
index 00000000..5155f6cb
--- /dev/null
+++ b/elfutils/tests/dwflmodtest.c
@@ -0,0 +1,248 @@
+/* Test program for libdwfl basic module tracking, relocation.
+ Copyright (C) 2005 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <locale.h>
+#include <argp.h>
+#include <libdwfl.h>
+#include <dwarf.h>
+
+static bool show_inlines;
+
+struct info
+{
+ Dwarf_Die *cudie;
+ Dwarf_Addr dwbias;
+};
+
+static int
+print_instance (Dwarf_Die *instance, void *arg)
+{
+ const struct info *info = arg;
+
+ printf (" inlined");
+
+ Dwarf_Files *files;
+ if (dwarf_getsrcfiles (info->cudie, &files, NULL) == 0)
+ {
+ Dwarf_Attribute attr_mem;
+ Dwarf_Word val;
+ if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_file,
+ &attr_mem), &val) == 0)
+ {
+ const char *file = dwarf_filesrc (files, val, NULL, NULL);
+ int lineno = 0, colno = 0;
+ if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_line,
+ &attr_mem), &val) == 0)
+ lineno = val;
+ if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_column,
+ &attr_mem), &val) == 0)
+ colno = val;
+ if (lineno == 0)
+ {
+ if (file != NULL)
+ printf (" from %s", file);
+ }
+ else if (colno == 0)
+ printf (" at %s:%u", file, lineno);
+ else
+ printf (" at %s:%u:%u", file, lineno, colno);
+ }
+ }
+
+ Dwarf_Addr lo = -1, hi = -1, entry = -1;
+ if (dwarf_lowpc (instance, &lo) == 0)
+ lo += info->dwbias;
+ else
+ printf (" (lowpc => %s)", dwarf_errmsg (-1));
+ if (dwarf_highpc (instance, &hi) == 0)
+ hi += info->dwbias;
+ else
+ printf (" (highpc => %s)", dwarf_errmsg (-1));
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (instance, DW_AT_entry_pc,
+ &attr_mem);
+ if (attr != NULL)
+ {
+ if (INTUSE(dwarf_formaddr) (attr, &entry) == 0)
+ entry += info->dwbias;
+ else
+ printf (" (entrypc => %s)", dwarf_errmsg (-1));
+ }
+
+ if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1)
+ printf (" %#" PRIx64 "..%#" PRIx64, lo, hi);
+ if (entry != (Dwarf_Addr) -1)
+ printf (" => %#" PRIx64 "\n", entry);
+ else
+ puts ("");
+
+ return DWARF_CB_OK;
+}
+
+static void
+print_inline (Dwarf_Func *func, void *arg)
+{
+ if (dwarf_func_inline_instances (func, &print_instance, arg) != 0)
+ printf (" error finding instances: %s\n", dwarf_errmsg (-1));
+}
+
+static int
+print_func (Dwarf_Func *func, void *arg)
+{
+ const struct info *info = arg;
+
+ const char *file = dwarf_func_file (func);
+ int line = -1;
+ dwarf_func_line (func, &line);
+ const char *fct = dwarf_func_name (func);
+
+ printf (" %s:%d: %s:", file, line, fct);
+
+ if (dwarf_func_inline (func))
+ {
+ puts (" inline function");
+ if (show_inlines)
+ print_inline (func, arg);
+ }
+ else
+ {
+ Dwarf_Addr lo = -1, hi = -1, entry = -1;
+ if (dwarf_func_lowpc (func, &lo) == 0)
+ lo += info->dwbias;
+ else
+ printf (" (lowpc => %s)", dwarf_errmsg (-1));
+ if (dwarf_func_highpc (func, &hi) == 0)
+ hi += info->dwbias;
+ else
+ printf (" (highpc => %s)", dwarf_errmsg (-1));
+ if (dwarf_func_entrypc (func, &entry) == 0)
+ entry += info->dwbias;
+ else
+ printf (" (entrypc => %s)", dwarf_errmsg (-1));
+
+ if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
+ || entry != (Dwarf_Addr) -1)
+ printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
+ lo, hi, entry);
+ else
+ puts ("");
+ }
+
+ return DWARF_CB_OK;
+}
+
+static int
+print_module (Dwfl_Module *mod __attribute__ ((unused)),
+ void **userdata __attribute__ ((unused)),
+ const char *name, Dwarf_Addr base,
+ Dwarf *dw, Dwarf_Addr bias,
+ void *arg)
+{
+ printf ("module: %30s %08" PRIx64 " %12p %" PRIx64 " (%s)\n",
+ name, base, dw, bias, dwfl_errmsg (-1));
+
+ if (dw != NULL && *(const bool *) arg)
+ {
+ Dwarf_Off off = 0;
+ size_t cuhl;
+ Dwarf_Off noff;
+
+ while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+ {
+ Dwarf_Die die_mem;
+ struct info info = { dwarf_offdie (dw, off + cuhl, &die_mem), bias };
+ (void) dwarf_getfuncs (info.cudie, print_func, &info, 0);
+
+ off = noff;
+ }
+ }
+
+ return DWARF_CB_OK;
+}
+
+static bool show_functions;
+
+static const struct argp_option options[] =
+ {
+ { "functions", 'f', NULL, 0, N_("Additionally show function names"), 0 },
+ { "inlines", 'i', NULL, 0, N_("Show instances of inlined functions"), 0 },
+ { NULL, 0, NULL, 0, NULL, 0 }
+ };
+
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+ struct argp_state *state __attribute__ ((unused)))
+{
+ switch (key)
+ {
+ case ARGP_KEY_INIT:
+ state->child_inputs[0] = state->input;
+ break;
+
+ case 'f':
+ show_functions = true;
+ break;
+
+ case 'i':
+ show_inlines = show_functions = true;
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ /* We use no threads here which can interfere with handling a stream. */
+ (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+ /* Set locale. */
+ (void) setlocale (LC_ALL, "");
+
+ Dwfl *dwfl = NULL;
+ const struct argp_child argp_children[] =
+ {
+ { .argp = dwfl_standard_argp () },
+ { .argp = NULL }
+ };
+ const struct argp argp =
+ {
+ options, parse_opt, NULL, NULL, argp_children, NULL, NULL
+ };
+ (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
+ assert (dwfl != NULL);
+
+ ptrdiff_t p = 0;
+ do
+ p = dwfl_getdwarf (dwfl, &print_module, &show_functions, p);
+ while (p > 0);
+ if (p < 0)
+ error (2, 0, "dwfl_getdwarf: %s", dwfl_errmsg (-1));
+
+ dwfl_end (dwfl);
+
+ return 0;
+}
diff --git a/elfutils/tests/get-files.c b/elfutils/tests/get-files.c
index 537d1eac..1294342c 100644
--- a/elfutils/tests/get-files.c
+++ b/elfutils/tests/get-files.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Red Hat, Inc.
+/* Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -68,8 +68,8 @@ main (int argc, char *argv[])
break;
}
- for (int i = 0; i < nfiles; ++i)
- printf (" file[%d] = \"%s\"\n", i,
+ for (size_t i = 0; i < nfiles; ++i)
+ printf (" file[%zu] = \"%s\"\n", i,
dwarf_filesrc (files, i, NULL, NULL));
o = ncu;
diff --git a/elfutils/tests/get-pubnames.c b/elfutils/tests/get-pubnames.c
index 3523f72f..e2791a29 100644
--- a/elfutils/tests/get-pubnames.c
+++ b/elfutils/tests/get-pubnames.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -21,7 +21,7 @@
static int globcnt;
static int
-callback (Dwarf *dbg, Dwarf_Global *gl, void *arg)
+callback (Dwarf *dbg, Dwarf_Global *gl, void *arg __attribute__ ((unused)))
{
int result = DWARF_CB_OK;
diff --git a/elfutils/tests/line2addr.c b/elfutils/tests/line2addr.c
index d2017fba..73c57f49 100644
--- a/elfutils/tests/line2addr.c
+++ b/elfutils/tests/line2addr.c
@@ -1,64 +1,125 @@
-#include <fcntl.h>
#include <inttypes.h>
-#include <libdw.h>
+#include <assert.h>
+#include <libdwfl.h>
+#include <argp.h>
#include <stdio.h>
+#include <locale.h>
#include <stdlib.h>
-#include <unistd.h>
+#include <string.h>
+#include <error.h>
+static void
+print_address (Dwfl_Module *mod, Dwarf_Addr address)
+{
+ int n = dwfl_module_relocations (mod);
+ if (n < 0)
+ error (0, 0, "dwfl_module_relocations: %s", dwfl_errmsg (-1));
+ else if (n > 0)
+ {
+ int i = dwfl_module_relocate_address (mod, &address);
+ if (i < 0)
+ error (0, 0, "dwfl_module_relocate_address: %s", dwfl_errmsg (-1));
+ else
+ {
+ const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+ const char *secname = dwfl_module_relocation_info (mod, i, NULL);
+ if (n > 1 || secname[0] != '\0')
+ printf ("%s(%s)+%#" PRIx64, modname, secname, address);
+ else
+ printf ("%s(%s)+%#" PRIx64, modname, secname, address);
+ return;
+ }
+ }
+
+ printf ("%#" PRIx64, address);
+}
+
+
+struct args
+{
+ const char *arg;
+ char *file;
+ int line;
+};
+
+static int
+handle_module (Dwfl_Module *mod __attribute__ ((unused)),
+ void **udata __attribute__ ((unused)),
+ const char *modname, Dwarf_Addr base __attribute__ ((unused)),
+ Dwarf *dbg __attribute__ ((unused)),
+ Dwarf_Addr bias __attribute__ ((unused)), void *arg)
+{
+ const struct args *const a = arg;
+
+ Dwfl_Line **lines = NULL;
+ size_t nlines = 0;
+
+ if (dwfl_module_getsrc_file (mod, a->file, a->line, 0, &lines, &nlines) == 0)
+ {
+ for (size_t inner = 0; inner < nlines; ++inner)
+ {
+ Dwarf_Addr addr;
+ int line = a->line, col = 0;
+ const char *file = dwfl_lineinfo (lines[inner], &addr, &line, &col,
+ NULL, NULL);
+ if (file != NULL)
+ {
+ printf ("%s -> ", a->arg);
+ print_address (mod, addr);
+ if (modname[0] != '\0')
+ printf (" (%s:", modname);
+ if (strcmp (file, a->file) || line != a->line || col != 0)
+ printf (" %s%s:%d", modname[0] != '\0' ? "" : "(",
+ file, line);
+ if (col != 0)
+ printf (":%d");
+ if (modname[0] != '\0'
+ || strcmp (file, a->file) || line != a->line || col != 0)
+ puts (")");
+ else
+ puts ("");
+ }
+ }
+ free (lines);
+ }
+
+ return DWARF_CB_OK;
+}
+
int
main (int argc, char *argv[])
{
- for (int cnt = 1; cnt < argc; ++cnt)
+ int cnt;
+
+ /* Set locale. */
+ (void) setlocale (LC_ALL, "");
+
+ Dwfl *dwfl = NULL;
+ (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &cnt, &dwfl);
+ assert (dwfl != NULL);
+
+ for (; cnt < argc; ++cnt)
{
- char *fname;
- char *file;
- int line;
+ struct args a = { .arg = argv[cnt] };
- switch (sscanf (argv[cnt], "%a[^:]:%a[^:]:%d",
- &fname, &file, &line))
+ switch (sscanf (a.arg, "%a[^:]:%d", &a.file, &a.line))
{
default:
case 0:
- case 1:
printf ("ignored %s\n", argv[cnt]);
continue;
- case 2:
- line = 0;
+ case 1:
+ a.line = 0;
break;
- case 3:
+ case 2:
break;
}
- int fd = open (fname, O_RDONLY);
- if (fd == -1)
- continue;
-
- Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
- if (dbg != NULL)
- {
- Dwarf_Line **lines = NULL;
- size_t nlines = 0;
-
- if (dwarf_getsrc_file (dbg, file, line, 0, &lines, &nlines) == 0)
- {
- for (size_t inner = 0; inner < nlines; ++inner)
- {
- Dwarf_Addr addr;
- if (dwarf_lineaddr (lines[inner], &addr) == 0)
- printf ("%s -> %#" PRIxMAX "\n",
- argv[cnt], (uintmax_t) addr);
- }
-
- free (lines);
- }
-
- dwarf_end (dbg);
- }
+ (void) dwfl_getdwarf (dwfl, &handle_module, &a, 0);
- close (fd);
- free (fname);
- free (file);
+ free (a.file);
}
return 0;
diff --git a/elfutils/tests/msg_tst.c b/elfutils/tests/msg_tst.c
index 67e63c0e..a3a93d05 100644
--- a/elfutils/tests/msg_tst.c
+++ b/elfutils/tests/msg_tst.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This program is Open Source software; you can redistribute it and/or
@@ -68,8 +68,8 @@ static struct
"only relocatable files can contain section groups" },
{ ELF_E_INVALID_PHDR,
"program header only allowed in executables and shared objects" },
- { ELF_E_NO_PHDR,
- "file has no program header" }
+ { ELF_E_NO_PHDR, "file has no program header" },
+ { ELF_E_INVALID_OFFSET, "invalid offset" }
};
diff --git a/elfutils/tests/newfile.c b/elfutils/tests/newfile.c
index 5efc862a..32c4091c 100644
--- a/elfutils/tests/newfile.c
+++ b/elfutils/tests/newfile.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+/* Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 1999.
This program is Open Source software; you can redistribute it and/or
@@ -46,7 +46,7 @@ print_ehdr (Elf32_Ehdr *ehdr)
}
int
-main (int argc, char *argv[])
+main (int argc, char *argv[] __attribute__ ((unused)))
{
Elf *elf;
int result = 0;
diff --git a/elfutils/tests/newscn.c b/elfutils/tests/newscn.c
index bc975130..8c8b335a 100644
--- a/elfutils/tests/newscn.c
+++ b/elfutils/tests/newscn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+/* Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
This program is Open Source software; you can redistribute it and/or
modify it under the terms of the Open Software License version 1.0 as
@@ -19,7 +19,7 @@
int
-main (int argc, char *argv[])
+main (void)
{
Elf *elf;
int fd;
diff --git a/elfutils/tests/run-addrscopes.sh b/elfutils/tests/run-addrscopes.sh
new file mode 100755
index 00000000..901d02e1
--- /dev/null
+++ b/elfutils/tests/run-addrscopes.sh
@@ -0,0 +1,31 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+#
+# This program is Open Source software; you can redistribute it and/or
+# modify it under the terms of the Open Software License version 1.0 as
+# published by the Open Source Initiative.
+#
+# You should have received a copy of the Open Software License along
+# with this program; if not, you may obtain a copy of the Open Software
+# License version 1.0 from http://www.opensource.org/licenses/osl.php or
+# by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+# 3001 King Ranch Road, Ukiah, CA 95482.
+set -e
+
+# Don't fail if we cannot decompress the file.
+bunzip2 -c $srcdir/testfile22.bz2 > testfile22 2>/dev/null || exit 0
+
+LD_LIBRARY_PATH=../libdw:../libebl:../libelf${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH \
+ ./addrscopes -e testfile22 0x8048353 >& addrscopes-test.out || :
+
+diff -Bbu addrscopes-test.out - <<\EOF
+0x8048353:
+ tests/foo.c (0x11): 0x8048348 (tests/foo.c:5) .. 0x804837e (tests/foo.c:16)
+ global [ be]
+ function (0x2e): 0x8048348 (tests/foo.c:5) .. 0x804835b (tests/foo.c:14)
+ local [ 8f]
+EOF
+
+rm -f testfile22 addrscopes-test.out
+
+exit 0
diff --git a/elfutils/tests/run-elflint-self.sh b/elfutils/tests/run-elflint-self.sh
new file mode 100755
index 00000000..df7678ab
--- /dev/null
+++ b/elfutils/tests/run-elflint-self.sh
@@ -0,0 +1,47 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This program is Open Source software; you can redistribute it and/or
+# modify it under the terms of the Open Software License version 1.0 as
+# published by the Open Source Initiative.
+#
+# You should have received a copy of the Open Software License along
+# with this program; if not, you may obtain a copy of the Open Software
+# License version 1.0 from http://www.opensource.org/licenses/osl.php or
+# by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+# 3001 King Ranch Road, Ukiah, CA 95482.
+set -e
+
+export LD_LIBRARY_PATH=../libebl:../libelf${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
+
+runtest() {
+# Uncomment for debuging
+# echo $1
+ if [ -f $1 ]; then
+ ../src/elflint --quiet --gnu-ld $1
+ fi
+}
+
+runtest ../src/addr2line
+runtest ../src/elfcmp
+runtest ../src/elflint
+runtest ../src/findtextrel
+runtest ../src/ld
+runtest ../src/nm
+runtest ../src/objdump
+runtest ../src/readelf
+runtest ../src/size
+runtest ../src/strip
+runtest ../libelf/libelf.so
+runtest ../libdw/libdw.so
+runtest ../libasm/libasm.so
+runtest ../libebl/libebl_alpha.so
+runtest ../libebl/libebl_arm.so
+runtest ../libebl/libebl_i386.so
+runtest ../libebl/libebl_ia64.so
+runtest ../libebl/libebl_ppc.so
+runtest ../libebl/libebl_ppc64.so
+runtest ../libebl/libebl_sh.so
+runtest ../libebl/libebl_sparc.so
+runtest ../libebl/libebl_x86_64.so
diff --git a/elfutils/tests/run-elflint-test.sh b/elfutils/tests/run-elflint-test.sh
new file mode 100755
index 00000000..f008ccdc
--- /dev/null
+++ b/elfutils/tests/run-elflint-test.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This program is Open Source software; you can redistribute it and/or
+# modify it under the terms of the Open Software License version 1.0 as
+# published by the Open Source Initiative.
+#
+# You should have received a copy of the Open Software License along
+# with this program; if not, you may obtain a copy of the Open Software
+# License version 1.0 from http://www.opensource.org/licenses/osl.php or
+# by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+# 3001 King Ranch Road, Ukiah, CA 95482.
+set -e
+
+# Don't fail if we cannot decompress the file.
+bunzip2 -c $srcdir/testfile18.bz2 > testfile18 2>/dev/null || exit 0
+
+LD_LIBRARY_PATH=../libebl:../libelf${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH \
+ ../src/elflint --gnu testfile18 >& elflint-test.out || :
+
+diff -u elflint-test.out - <<"EOF"
+section [ 8] '.rela.dyn': relocation 1: copy relocation against symbol of type FUNC
+EOF
+
+rm -f testfile18 elflint-test.out
+
+exit 0
diff --git a/elfutils/tests/run-line2addr.sh b/elfutils/tests/run-line2addr.sh
index c46c8fda..c103ae03 100755
--- a/elfutils/tests/run-line2addr.sh
+++ b/elfutils/tests/run-line2addr.sh
@@ -25,20 +25,31 @@ bunzip2 -c $srcdir/testfile8.bz2 > testfile8 2>/dev/null || exit 0
# Don't fail if we cannot decompress the file.
bunzip2 -c $srcdir/testfile14.bz2 > testfile14 2>/dev/null || exit 0
-./line2addr testfile:f.c:4 testfile:f.c:8 testfile2:m.c:6 testfile2:b.c:1 testfile8:strip.c:953 testfile8:strip.c:365 testfile14:v.c:6 > line2addr.out
+# Don't fail if we cannot decompress the file.
+bunzip2 -c $srcdir/testfile23.bz2 > testfile23 2>/dev/null || exit 0
+
+(./line2addr -e testfile f.c:4 testfile f.c:8
+ ./line2addr -e testfile2 m.c:6 b.c:1
+ ./line2addr -e testfile8 strip.c:953 strip.c:365
+ ./line2addr -e testfile14 v.c:6
+ ./line2addr -e testfile23 foo.c:2 foo.c:6
+) > line2addr.out
diff -u line2addr.out - <<"EOF"
-testfile:f.c:4 -> 0x804846b
-testfile2:m.c:6 -> 0x100004cc
-testfile2:b.c:1 -> 0x10000470
-testfile8:strip.c:953 -> 0x169f
-testfile8:strip.c:953 -> 0x16aa
-testfile8:strip.c:365 -> 0x278b
-testfile8:strip.c:365 -> 0x2797
-testfile14:v.c:6 -> 0x400468
-testfile14:v.c:6 -> 0x400487
+f.c:4 -> 0x804846b (/home/drepper/gnu/new-bu/build/ttt/f.c:4)
+m.c:6 -> 0x100004cc (/shoggoth/drepper/m.c:6)
+b.c:1 -> 0x10000470 (/shoggoth/drepper/b.c:4)
+strip.c:953 -> (.text)+0x169f (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:953)
+strip.c:953 -> (.text)+0x16aa (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:953)
+strip.c:365 -> (.text)+0x278b (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:365)
+strip.c:365 -> (.text)+0x2797 (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:365)
+v.c:6 -> 0x400468 (/home/drepper/local/elfutils-build/20050425/v.c:6)
+v.c:6 -> 0x400487 (/home/drepper/local/elfutils-build/20050425/v.c:6)
+foo.c:2 -> (.init.text)+0xc (/home/roland/stock-elfutils-build/foo.c:2)
+foo.c:6 -> (.text)+0xc (/home/roland/stock-elfutils-build/foo.c:6)
EOF
-rm -f testfile testfile2 testfile8 testfile14 line2addr.out
+rm -f testfile testfile2 testfile8 testfile14 testfile22 testfile23 \
+ line2addr.out
exit 0
diff --git a/elfutils/tests/run-ranlib-test.sh b/elfutils/tests/run-ranlib-test.sh
new file mode 100755
index 00000000..868e728e
--- /dev/null
+++ b/elfutils/tests/run-ranlib-test.sh
@@ -0,0 +1,34 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This program is Open Source software; you can redistribute it and/or
+# modify it under the terms of the Open Software License version 1.0 as
+# published by the Open Source Initiative.
+#
+# You should have received a copy of the Open Software License along
+# with this program; if not, you may obtain a copy of the Open Software
+# License version 1.0 from http://www.opensource.org/licenses/osl.php or
+# by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+# 3001 King Ranch Road, Ukiah, CA 95482.
+set -e
+
+cat > ranlib-test.a <<"EOF"
+!<arch>
+foo/ 1124128960 500 500 100664 4 `
+foo
+bar/ 1124128965 500 500 100664 4 `
+bar
+EOF
+
+cp ranlib-test.a ranlib-test.a-copy
+
+LD_LIBRARY_PATH=../libelf${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH \
+ ../src/ranlib ranlib-test.a
+
+# The ranlib call should not have changed anything.
+cmp ranlib-test.a ranlib-test.a-copy
+
+rm -f ranlib-test.a ranlib-test.a-copy
+
+exit 0
diff --git a/elfutils/tests/run-ranlib-test2.sh b/elfutils/tests/run-ranlib-test2.sh
new file mode 100755
index 00000000..cce9ca7c
--- /dev/null
+++ b/elfutils/tests/run-ranlib-test2.sh
@@ -0,0 +1,39 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This program is Open Source software; you can redistribute it and/or
+# modify it under the terms of the Open Software License version 1.0 as
+# published by the Open Source Initiative.
+#
+# You should have received a copy of the Open Software License along
+# with this program; if not, you may obtain a copy of the Open Software
+# License version 1.0 from http://www.opensource.org/licenses/osl.php or
+# by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+# 3001 King Ranch Road, Ukiah, CA 95482.
+set -e
+
+original=${original:-testfile19}
+indexed=${indexed:-testfile19.index}
+
+# Don't fail if we cannot decompress the file.
+bunzip2 -c $srcdir/$original.bz2 > $original 2>/dev/null || exit 0
+
+# Don't fail if we cannot decompress the file.
+bunzip2 -c $srcdir/$indexed.bz2 > $indexed 2>/dev/null || exit 0
+
+LD_LIBRARY_PATH=../libelf${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH \
+ ../src/ranlib $original
+
+if test -z "$noindex"; then
+ # The data in the index is different. The reference file has it blanked
+ # out, we do the same here.
+ echo " " |
+ dd of=$original seek=24 bs=1 count=12 conv=notrunc 2>/dev/null
+fi
+
+cmp $original $indexed
+
+rm -f $original $indexed
+
+exit 0
diff --git a/elfutils/tests/run-ranlib-test3.sh b/elfutils/tests/run-ranlib-test3.sh
new file mode 100755
index 00000000..f0300336
--- /dev/null
+++ b/elfutils/tests/run-ranlib-test3.sh
@@ -0,0 +1,17 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This program is Open Source software; you can redistribute it and/or
+# modify it under the terms of the Open Software License version 1.0 as
+# published by the Open Source Initiative.
+#
+# You should have received a copy of the Open Software License along
+# with this program; if not, you may obtain a copy of the Open Software
+# License version 1.0 from http://www.opensource.org/licenses/osl.php or
+# by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+# 3001 King Ranch Road, Ukiah, CA 95482.
+
+original=testfile20
+indexed=testfile20.index
+. $srcdir/run-ranlib-test2.sh
diff --git a/elfutils/tests/run-ranlib-test4.sh b/elfutils/tests/run-ranlib-test4.sh
new file mode 100755
index 00000000..78944ae9
--- /dev/null
+++ b/elfutils/tests/run-ranlib-test4.sh
@@ -0,0 +1,18 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This program is Open Source software; you can redistribute it and/or
+# modify it under the terms of the Open Software License version 1.0 as
+# published by the Open Source Initiative.
+#
+# You should have received a copy of the Open Software License along
+# with this program; if not, you may obtain a copy of the Open Software
+# License version 1.0 from http://www.opensource.org/licenses/osl.php or
+# by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+# 3001 King Ranch Road, Ukiah, CA 95482.
+
+original=testfile21
+indexed=testfile21.index
+noindex=1
+. $srcdir/run-ranlib-test2.sh
diff --git a/elfutils/tests/scnnames.c b/elfutils/tests/scnnames.c
index de30312e..14f428d0 100644
--- a/elfutils/tests/scnnames.c
+++ b/elfutils/tests/scnnames.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 1998.
This program is Open Source software; you can redistribute it and/or
@@ -29,6 +29,12 @@ main (int argc, char *argv[])
size_t strndx;
Elf_Scn *scn;
+ if (argc < 2)
+ {
+ puts ("missing parameter");
+ exit (1);
+ }
+
fd = open (argv[1], O_RDONLY);
if (fd == -1)
{
diff --git a/elfutils/tests/showptable.c b/elfutils/tests/showptable.c
index afc1f26d..21247c8b 100644
--- a/elfutils/tests/showptable.c
+++ b/elfutils/tests/showptable.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 1998.
This program is Open Source software; you can redistribute it and/or
@@ -28,6 +28,12 @@ main (int argc, char *argv[])
GElf_Ehdr ehdr;
int cnt;
+ if (argc < 2)
+ {
+ puts ("missing parameter");
+ exit (1);
+ }
+
fd = open (argv[1], O_RDONLY);
if (fd == -1)
{
diff --git a/elfutils/tests/test-nlist.c b/elfutils/tests/test-nlist.c
index 40eb320a..1a3f3ec2 100644
--- a/elfutils/tests/test-nlist.c
+++ b/elfutils/tests/test-nlist.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Red Hat, Inc.
+/* Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is Open Source software; you can redistribute it and/or
@@ -28,7 +28,7 @@ foo (int a)
}
int
-main (int argc, char *argv[])
+main (int argc, char *argv[] __attribute__ ((unused)))
{
struct nlist nl[6] =
{
diff --git a/elfutils/tests/testfile18.bz2 b/elfutils/tests/testfile18.bz2
new file mode 100644
index 00000000..8b5326cc
--- /dev/null
+++ b/elfutils/tests/testfile18.bz2
Binary files differ
diff --git a/elfutils/tests/testfile19.bz2 b/elfutils/tests/testfile19.bz2
new file mode 100644
index 00000000..f3e6512e
--- /dev/null
+++ b/elfutils/tests/testfile19.bz2
Binary files differ
diff --git a/elfutils/tests/testfile19.index.bz2 b/elfutils/tests/testfile19.index.bz2
new file mode 100644
index 00000000..c0a0a7ac
--- /dev/null
+++ b/elfutils/tests/testfile19.index.bz2
Binary files differ
diff --git a/elfutils/tests/testfile20.bz2 b/elfutils/tests/testfile20.bz2
new file mode 100644
index 00000000..a379f6bf
--- /dev/null
+++ b/elfutils/tests/testfile20.bz2
Binary files differ
diff --git a/elfutils/tests/testfile20.index.bz2 b/elfutils/tests/testfile20.index.bz2
new file mode 100644
index 00000000..08dedaf4
--- /dev/null
+++ b/elfutils/tests/testfile20.index.bz2
Binary files differ
diff --git a/elfutils/tests/testfile21.bz2 b/elfutils/tests/testfile21.bz2
new file mode 100644
index 00000000..bab7e6d1
--- /dev/null
+++ b/elfutils/tests/testfile21.bz2
Binary files differ
diff --git a/elfutils/tests/testfile21.index.bz2 b/elfutils/tests/testfile21.index.bz2
new file mode 100644
index 00000000..5192219b
--- /dev/null
+++ b/elfutils/tests/testfile21.index.bz2
Binary files differ
diff --git a/elfutils/tests/testfile22.bz2 b/elfutils/tests/testfile22.bz2
new file mode 100644
index 00000000..8c262709
--- /dev/null
+++ b/elfutils/tests/testfile22.bz2
Binary files differ
diff --git a/elfutils/tests/testfile23.bz2 b/elfutils/tests/testfile23.bz2
new file mode 100644
index 00000000..cf0ce559
--- /dev/null
+++ b/elfutils/tests/testfile23.bz2
Binary files differ
diff --git a/elfutils/tests/update1.c b/elfutils/tests/update1.c
index decb09ba..cf2d625c 100644
--- a/elfutils/tests/update1.c
+++ b/elfutils/tests/update1.c
@@ -1,5 +1,5 @@
/* Test program for elf_update function.
- Copyright (C) 2000, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is Open Source software; you can redistribute it and/or
@@ -25,7 +25,7 @@
int
-main (int argc, char *argv[])
+main (int argc, char *argv[] __attribute__ ((unused)))
{
const char *fname = "xxx";
int fd;
diff --git a/elfutils/tests/update2.c b/elfutils/tests/update2.c
index c595fba7..743bfd21 100644
--- a/elfutils/tests/update2.c
+++ b/elfutils/tests/update2.c
@@ -1,5 +1,5 @@
/* Test program for elf_update function.
- Copyright (C) 2000, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is Open Source software; you can redistribute it and/or
@@ -25,7 +25,7 @@
int
-main (int argc, char *argv[])
+main (int argc, char *argv[] __attribute__ ((unused)))
{
const char *fname = "xxx";
int fd;
diff --git a/elfutils/tests/update3.c b/elfutils/tests/update3.c
index 06bc8ff6..160adf1e 100644
--- a/elfutils/tests/update3.c
+++ b/elfutils/tests/update3.c
@@ -1,5 +1,5 @@
/* Test program for elf_update function.
- Copyright (C) 2000, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is Open Source software; you can redistribute it and/or
@@ -27,7 +27,7 @@
int
-main (int argc, char *argv[])
+main (int argc, char *argv[] __attribute__ ((unused)))
{
const char *fname = "xxx";
int fd;
diff --git a/elfutils/tests/update4.c b/elfutils/tests/update4.c
index 17ef4702..30f3a07d 100644
--- a/elfutils/tests/update4.c
+++ b/elfutils/tests/update4.c
@@ -1,5 +1,5 @@
/* Test program for elf_update function.
- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is Open Source software; you can redistribute it and/or
@@ -28,7 +28,7 @@
int
-main (int argc, char *argv[])
+main (int argc, char *argv[] __attribute__ ((unused)))
{
const char fname[] = "xxx";
int fd;