diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-07-26 05:00:05 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-07-26 05:00:05 +0000 |
commit | b08d5a8fb42f4586d756068065186b5af7e48dad (patch) | |
tree | 9f05f86be7877ed461b4dc05f53b29ea4fc0d2a1 /libebl | |
download | elfutils-b08d5a8fb42f4586d756068065186b5af7e48dad.tar.gz |
Adjust for monotone.
Diffstat (limited to 'libebl')
82 files changed, 6708 insertions, 0 deletions
diff --git a/libebl/.cvsignore b/libebl/.cvsignore new file mode 100644 index 00000000..70845e08 --- /dev/null +++ b/libebl/.cvsignore @@ -0,0 +1 @@ +Makefile.in diff --git a/libebl/ChangeLog b/libebl/ChangeLog new file mode 100644 index 00000000..a14572c0 --- /dev/null +++ b/libebl/ChangeLog @@ -0,0 +1,281 @@ +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. + * eblopenbackend.c (default_reloc_simple_type): New function. + (openbackend): Use that as default reloc_simple_type callback. + * eblrelocsimpletype.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * i386_symbol.c (i386_reloc_simple_type): New function. + * libebl_i386.h: Declare it. + * i386_init.c (i386_init): Use it. + * x86_64_symbol.c (x86_64_reloc_simple_type): New function. + * libebl_x86_64.h: Declare it. + * x86_64_init.c (x86_64_init): Use it. + * ppc_symbol.c (ppc_reloc_simple_type): New function. + * libebl_ppc.h: Declare it. + * ppc_init.c (ppc_init): Use it. + * ppc64_symbol.c (ppc64_reloc_simple_type): New function. + * libebl_ppc64.h: Declare it. + * ppc64_init.c (ppc64_init): Use it. + +2005-03-17 Ulrich Drepper <drepper@redhat.com> + + * eblcorenote.c (ebl_core_note): Add support for AT_SECURE. + +2005-02-15 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (AM_CFLAGS): Add -Wformat=2. + +2005-02-14 Ulrich Drepper <drepper@redhat.com> + + * alpha_destr.c: Add __attribute__((unused)) where needed. + * alpha_init.c: Likewise. + * alpha_symbol.c: Likewise. + * arm_destr.c: Likewise. + * arm_init.c: Likewise. + * arm_symbol.c: Likewise. + * i386_corenote.c: Likewise. + * i386_destr.c: Likewise. + * i386_init.c: Likewise. + * i386_symbol.c: Likewise. + * ia64_destr.c: Likewise. + * ia64_init.c: Likewise. + * ia64_symbol.c: Likewise. + * mips_destr.c: Likewise. + * mips_init.c: Likewise. + * mips_symbol.c: Likewise. + * ppc64_destr.c: Likewise. + * ppc64_init.c: Likewise. + * ppc64_symbol.c: Likewise. + * ppc_destr.c: Likewise. + * ppc_init.c: Likewise. + * ppc_symbol.c: Likewise. + * sh_destr.c: Likewise. + * sh_init.c: Likewise. + * sh_symbol.c: Likewise. + * sparc_destr.c: Likewise. + * sparc_init.c: Likewise. + * sparc_symbol.c: Likewise. + * x86_64_destr.c: Likewise. + * x86_64_init.c: Likewise. + * x86_64_symbol.c: Likewise. + + * x86_64_symbol.c (reloc_map_table): Fix entries for R_X86_64_64 + and R_X86_64_32.. + +2005-02-06 Ulrich Drepper <drepper@redhat.com> + + * eblstrtab.c: A few cleanups. + + * eblopenbackend.c: Mark unused parameters. + + * eblgstrtab.c: Cleanups a few printf format strings. + + * Makefile.am: Cleanup AM_CFLAGS handling. Add -Wunused -Wextra. + +2005-02-05 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Check for text relocations in constructed DSOs. + + * eblstrtab.c: Minor cleanups. + + * Makefile.am (AM_CFLAGS): Add -std=gnu99 and -fmudflap for MUDFLAP. + +2004-08-16 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (AM_CFLAGS): Add LIBSTR definition with base name of + the lib directory. + * eblopenbackend.c (openbackend): Use LIBSTR instead of hardcoded + lib in path to ebl modules. + +2004-04-01 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Add rules for ppc and ppc64 ebl module. + * ppc_init..c: New file. + * ppc_destr.c: New file. + * ppc_symbol.c: New file. + * libebl_ppc.h: New file. + * libebl_ppc.map: New file. + * ppc64_init..c: New file. + * ppc64_destr.c: New file. + * ppc64_symbol.c: New file. + * libebl_ppc64.h: New file. + * libebl_ppc64.map: New file. + +2004-01-20 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Support building with mudflap. + +2004-01-18 Ulrich Drepper <drepper@redhat.com> + + * libeblP.h (_): Use elfutils domain. + +2004-01-16 Ulrich Drepper <drepper@redhat.com> + + * eblsectionname.c: Add support for SHN_BEFORE and SHN_AFTER. + +2004-01-13 Ulrich Drepper <drepper@redhat.com> + + * eblsegmenttypename.c ((ebl_segment_type_name): Add support for + PT_GNU_RELRO. + +2004-01-08 Ulrich Drepper <drepper@redhat.com> + + * libebl.h: Remove last traces of libtool. + +2004-01-05 Ulrich Drepper <drepper@redhat.com> + + * elf-knowledge.h: Move to libelf subdir. + + * Makefile.am (EXTRA_DIST): Remove libebl.map. + * libebl.map: Removed. + +2003-12-08 Ulrich Drepper <drepper@redhat.com> + + * eblsectiontypename.c (ebl_section_type_name): Add support for + SHT_SUNW_move, SHT_CHECKSUM, and SHT_GNU_LIBLIST. + +2003-11-19 Ulrich Drepper <drepper@redhat.com> + + * ia64_symbol.c (ia64_dynamic_tag_name): New function. + * libebl_ia64.h (ia64_dynamic_tag_name): Declare. + * ia64_init.c (ia64_init): Register i164_dynamic_tag_name. + +2003-09-24 Ulrich Drepper <drepper@redhat.com> + + * ia64_init.c (ia64_init): Initialize segment_type_name callback. + * ia64_symbol.c (ia64_segment_type_name): Define. + * libebl_ia64.h (ia64_segment_type_name): Declare. + +2003-09-22 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (AM_CFLAGS): Add -fpic. + +2003-08-14 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (install): Remove dependency on libebl.so. + +2003-08-13 Ulrich Drepper <drepper@redhat.com> + + * eblopenbackend.c: Adjust relative path to arch-specific DSOs + assuming the code ends up in the application. Add second dlopen() + try without any path, just the filename. + * Makefile.in: Remove rules to build and install libebl.so. + +2003-08-11 Ulrich Drepper <drepper@redhat.com> + + * Moved to CVS archive. diff --git a/libebl/Makefile.am b/libebl/Makefile.am new file mode 100644 index 00000000..5f7be50b --- /dev/null +++ b/libebl/Makefile.am @@ -0,0 +1,201 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2000, 2001, 2002, 2003, 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 +## 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 -DOBJDIR=\"$(shell pwd)\" +if MUDFLAP +AM_CFLAGS = -fmudflap +else +AM_CFLAGS = +endif +AM_CFLAGS += -fpic -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 \ + -std=gnu99 + +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 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 +noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so) + +euincludedir = $(includedir)/elfutils +euinclude_HEADERS = libebl.h + +gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \ + eblreloctypename.c eblsegmenttypename.c \ + eblsectiontypename.c eblmachineflagname.c \ + eblsymboltypename.c ebldynamictagname.c eblsectionname.c \ + eblobjecttypename.c eblsymbolbindingname.c \ + eblbackendname.c eblshflagscombine.c eblwstrtab.c \ + eblgstrtab.c eblosabiname.c eblmachineflagcheck.c \ + eblreloctypecheck.c eblrelocvaliduse.c eblrelocsimpletype.c \ + ebldynamictagcheck.c eblcorenotetypename.c eblobjnotetypename.c \ + eblcorenote.c eblobjnote.c ebldebugscnp.c \ + eblgotpcreloccheck.c eblcopyrelocp.c eblsectionstripp.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 = $(i386_SRCS) +am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os) + +if MUDFLAP +libelf = ../libelf/libelf.a +libmudflap = -lmudflap +else +libelf = ../libelf/libelf.so +libmudflap = +endif + +textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi + +libebl_i386_so_SOURCES = +libebl_i386.so: libebl_i386_pic.a libebl_i386.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_i386.map \ + -Wl,-z,defs $(libelf) $(libmudflap) + $(textrel_check) + + +sh_SRCS = sh_init.c sh_destr.c sh_symbol.c +libebl_sh_pic_a_SOURCES = $(sh_SRCS) +am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os) + +libebl_sh_so_SOURCES = +libebl_sh.so: libebl_sh_pic.a libebl_sh.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_sh.map \ + -Wl,-z,defs $(libmudflap) + $(textrel_check) + + +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 = +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 \ + -Wl,-z,defs $(libelf) $(libmudflap) + $(textrel_check) + + +ia64_SRCS = ia64_init.c ia64_destr.c ia64_symbol.c +libebl_ia64_pic_a_SOURCES = $(ia64_SRCS) +am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os) + +libebl_ia64_so_SOURCES = +libebl_ia64.so: libebl_ia64_pic.a libebl_ia64.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_ia64.map \ + -Wl,-z,defs $(libmudflap) + $(textrel_check) + + +alpha_SRCS = alpha_init.c alpha_destr.c alpha_symbol.c +libebl_alpha_pic_a_SOURCES = $(alpha_SRCS) +am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os) + +libebl_alpha_so_SOURCES = +libebl_alpha.so: libebl_alpha_pic.a libebl_alpha.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_alpha.map \ + -Wl,-z,defs $(libmudflap) + $(textrel_check) + + +arm_SRCS = arm_init.c arm_destr.c arm_symbol.c +libebl_arm_pic_a_SOURCES = $(arm_SRCS) +am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os) + +libebl_arm_so_SOURCES = +libebl_arm.so: libebl_arm_pic.a libebl_arm.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_arm.map \ + -Wl,-z,defs $(libmudflap) + $(textrel_check) + + +sparc_SRCS = sparc_init.c sparc_destr.c sparc_symbol.c +libebl_sparc_pic_a_SOURCES = $(sparc_SRCS) +am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os) + +libebl_sparc_so_SOURCES = +libebl_sparc.so: libebl_sparc_pic.a libebl_sparc.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_sparc.map \ + -Wl,-z,defs $(libmudflap) + $(textrel_check) + + +ppc_SRCS = ppc_init.c ppc_destr.c ppc_symbol.c +libebl_ppc_pic_a_SOURCES = $(ppc_SRCS) +am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os) + +libebl_ppc_so_SOURCES = +libebl_ppc.so: libebl_ppc_pic.a libebl_ppc.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_ppc.map \ + -Wl,-z,defs $(libelf) $(libmudflap) + $(textrel_check) + + +ppc64_SRCS = ppc64_init.c ppc64_destr.c ppc64_symbol.c +libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS) +am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os) + +libebl_ppc64_so_SOURCES = +libebl_ppc64.so: libebl_ppc64_pic.a libebl_ppc64.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libebl_ppc64.map \ + -Wl,-z,defs $(libelf) $(libmudflap) + $(textrel_check) + + +%.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 + +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)/$(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)/$(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)/$(LIBEBL_SUBDIR) + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils + +noinst_HEADERS = libeblP.h $(noinst_LIBRARIES:%_pic.a=%.h) +EXTRA_DIST = $(noinst_LIBRARIES:%_pic.a=%.map) \ + $(foreach m,$(modules),$($(m)_SRCS)) + +CLEANFILES = $(am_libebl_pic_a_OBJECTS) \ + $(foreach m,$(modules),$(am_libebl_$(m)_pic_a_OBJECTS)) diff --git a/libebl/alpha_destr.c b/libebl/alpha_destr.c new file mode 100644 index 00000000..4fc5cf85 --- /dev/null +++ b/libebl/alpha_destr.c @@ -0,0 +1,27 @@ +/* Destructor for Alpha specific backend library. + 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 + 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_alpha.h> + + +void +alpha_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/alpha_init.c b/libebl/alpha_init.c new file mode 100644 index 00000000..17eff373 --- /dev/null +++ b/libebl/alpha_init.c @@ -0,0 +1,41 @@ +/* Initialization of Alpha specific backend library. + 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 + 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_alpha.h> + + +const char * +alpha_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 NULL; + + /* We handle it. */ + eh->name = "Alpha"; + eh->reloc_type_name = alpha_reloc_type_name; + eh->reloc_type_check = alpha_reloc_type_check; + eh->copy_reloc_p = alpha_copy_reloc_p; + eh->destr = alpha_destr; + + return MODVERSION; +} diff --git a/libebl/alpha_symbol.c b/libebl/alpha_symbol.c new file mode 100644 index 00000000..49e7c72f --- /dev/null +++ b/libebl/alpha_symbol.c @@ -0,0 +1,101 @@ +/* Alpha specific symbolic name handling. + 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 + 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_alpha.h> + + +/* Return of the backend. */ +const char * +alpha_backend_name (void) +{ + return "alpha"; +} + + +/* Relocation mapping table. */ +static const char *reloc_map_table[] = + { + [R_ALPHA_NONE] = "R_ALPHA_NONE", + [R_ALPHA_REFLONG] = "R_ALPHA_REFLONG", + [R_ALPHA_REFQUAD] = "R_ALPHA_REFQUAD", + [R_ALPHA_GPREL32] = "R_ALPHA_GPREL32", + [R_ALPHA_LITERAL] = "R_ALPHA_LITERAL", + [R_ALPHA_LITUSE] = "R_ALPHA_LITUSE", + [R_ALPHA_GPDISP] = "R_ALPHA_GPDISP", + [R_ALPHA_BRADDR] = "R_ALPHA_BRADDR", + [R_ALPHA_HINT] = "R_ALPHA_HINT", + [R_ALPHA_SREL16] = "R_ALPHA_SREL16", + [R_ALPHA_SREL32] = "R_ALPHA_SREL32", + [R_ALPHA_SREL64] = "R_ALPHA_SREL64", + [R_ALPHA_GPRELHIGH] = "R_ALPHA_GPRELHIGH", + [R_ALPHA_GPRELLOW] = "R_ALPHA_GPRELLOW", + [R_ALPHA_GPREL16] = "R_ALPHA_GPREL16", + [R_ALPHA_COPY] = "R_ALPHA_COPY", + [R_ALPHA_GLOB_DAT] = "R_ALPHA_GLOB_DAT", + [R_ALPHA_JMP_SLOT] = "R_ALPHA_JMP_SLOT", + [R_ALPHA_RELATIVE] = "R_ALPHA_RELATIVE", + [R_ALPHA_TLS_GD_HI] = "R_ALPHA_TLS_GD_HI", + [R_ALPHA_TLSGD] = "R_ALPHA_TLSGD", + [R_ALPHA_TLS_LDM] = "R_ALPHA_TLS_LDM", + [R_ALPHA_DTPMOD64] = "R_ALPHA_DTPMOD64", + [R_ALPHA_GOTDTPREL] = "R_ALPHA_GOTDTPREL", + [R_ALPHA_DTPREL64] = "R_ALPHA_DTPREL64", + [R_ALPHA_DTPRELHI] = "R_ALPHA_DTPRELHI", + [R_ALPHA_DTPRELLO] = "R_ALPHA_DTPRELLO", + [R_ALPHA_DTPREL16] = "R_ALPHA_DTPREL16", + [R_ALPHA_GOTTPREL] = "R_ALPHA_GOTTPREL", + [R_ALPHA_TPREL64] = "R_ALPHA_TPREL64", + [R_ALPHA_TPRELHI] = "R_ALPHA_TPRELHI", + [R_ALPHA_TPRELLO] = "R_ALPHA_TPRELLO", + [R_ALPHA_TPREL16] = "R_ALPHA_TPREL16" + }; + + +/* Determine relocation type string for Alpha. */ +const char * +alpha_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type < 0 + || ((size_t) type + >= sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))) + return NULL; + + return reloc_map_table[type]; +} + + +/* Check for correct relocation type. */ +bool +alpha_reloc_type_check (int type) +{ + return (type >= R_ALPHA_NONE + && ((size_t) type + < sizeof (reloc_map_table) / sizeof (reloc_map_table[0])) + && reloc_map_table[type] != NULL) ? true : false; +} + +/* Check whether given relocation is a copy relocation. */ +bool +alpha_copy_reloc_p (int reloc) +{ + return reloc == R_ALPHA_COPY; +} diff --git a/libebl/arm_destr.c b/libebl/arm_destr.c new file mode 100644 index 00000000..2675720a --- /dev/null +++ b/libebl/arm_destr.c @@ -0,0 +1,27 @@ +/* Destructor for Arm specific backend library. + 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 + 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_arm.h> + + +void +arm_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/arm_init.c b/libebl/arm_init.c new file mode 100644 index 00000000..a0a65f83 --- /dev/null +++ b/libebl/arm_init.c @@ -0,0 +1,41 @@ +/* Initialization of Arm specific backend library. + 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 + 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_arm.h> + + +const char * +arm_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 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 MODVERSION; +} diff --git a/libebl/arm_symbol.c b/libebl/arm_symbol.c new file mode 100644 index 00000000..f4de8be9 --- /dev/null +++ b/libebl/arm_symbol.c @@ -0,0 +1,121 @@ +/* Arm specific symbolic name handling. + 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 + 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_arm.h> + + +/* Return of the backend. */ +const char * +arm_backend_name (void) +{ + return "arm"; +} + + +/* Relocation mapping table. */ +static const char *reloc_map_table[] = + { + [R_ARM_NONE] = "R_ARM_NONE", + [R_ARM_PC24] = "R_ARM_PC24", + [R_ARM_ABS32] = "R_ARM_ABS32", + [R_ARM_REL32] = "R_ARM_REL32", + [R_ARM_PC13] = "R_ARM_PC13", + [R_ARM_ABS16] = "R_ARM_ABS16", + [R_ARM_ABS12] = "R_ARM_ABS12", + [R_ARM_THM_ABS5] = "R_ARM_THM_ABS5", + [R_ARM_ABS8] = "R_ARM_ABS8", + [R_ARM_SBREL32] = "R_ARM_SBREL32", + [R_ARM_THM_PC22] = "R_ARM_THM_PC22", + [R_ARM_THM_PC8] = "R_ARM_THM_PC8", + [R_ARM_AMP_VCALL9] = "R_ARM_AMP_VCALL9", + [R_ARM_SWI24] = "R_ARM_SWI24", + [R_ARM_THM_SWI8] = "R_ARM_THM_SWI8", + [R_ARM_XPC25] = "R_ARM_XPC25", + [R_ARM_THM_XPC22] = "R_ARM_THM_XPC22", + [R_ARM_COPY] = "R_ARM_COPY", + [R_ARM_GLOB_DAT] = "R_ARM_GLOB_DAT", + [R_ARM_JUMP_SLOT] = "R_ARM_JUMP_SLOT", + [R_ARM_RELATIVE] = "R_ARM_RELATIVE", + [R_ARM_GOTOFF] = "R_ARM_GOTOFF", + [R_ARM_GOTPC] = "R_ARM_GOTPC", + [R_ARM_GOT32] = "R_ARM_GOT32", + [R_ARM_PLT32] = "R_ARM_PLT32", + [R_ARM_ALU_PCREL_7_0] = "R_ARM_ALU_PCREL_7_0", + [R_ARM_ALU_PCREL_15_8] = "R_ARM_ALU_PCREL_15_8", + [R_ARM_ALU_PCREL_23_15] = "R_ARM_ALU_PCREL_23_15", + [R_ARM_LDR_SBREL_11_0] = "R_ARM_LDR_SBREL_11_0", + [R_ARM_ALU_SBREL_19_12] = "R_ARM_ALU_SBREL_19_12", + [R_ARM_ALU_SBREL_27_20] = "R_ARM_ALU_SBREL_27_20" + }; + +static const char *reloc_map_table2[] = + { + [R_ARM_GNU_VTENTRY] = "R_ARM_GNU_VTENTRY", + [R_ARM_GNU_VTINHERIT] = "R_ARM_GNU_VTINHERIT", + [R_ARM_THM_PC11] = "R_ARM_THM_PC11", + [R_ARM_THM_PC9] = "R_ARM_THM_PC9" + }; + +static const char *reloc_map_table3[] = + { + [R_ARM_RXPC25] = "R_ARM_RXPC25", + [R_ARM_RSBREL32] = "R_ARM_RSBREL32", + [R_ARM_THM_RPC22] = "R_ARM_THM_RPC22", + [R_ARM_RREL32] = "R_ARM_RREL32", + [R_ARM_RABS22] = "R_ARM_RABS22", + [R_ARM_RPC24] = "R_ARM_RPC24", + [R_ARM_RBASE] = "R_ARM_RBASE" + }; + + +/* Determine relocation type string for Alpha. */ +const char * +arm_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type >= R_ARM_NONE && type <= R_ARM_ALU_SBREL_27_20) + return reloc_map_table[type]; + + if (type >= R_ARM_GNU_VTENTRY && type <= R_ARM_THM_PC9) + return reloc_map_table2[type - R_ARM_GNU_VTENTRY]; + + if (type >= R_ARM_RXPC25 && type <= R_ARM_RBASE) + return reloc_map_table3[type - R_ARM_RXPC25]; + + return NULL; +} + + +/* Check for correct relocation type. */ +bool +arm_reloc_type_check (int type) +{ + return ((type >= R_ARM_NONE && type <= R_ARM_ALU_SBREL_27_20) + || (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/libebl/eblbackendname.c b/libebl/eblbackendname.c new file mode 100644 index 00000000..03830ebe --- /dev/null +++ b/libebl/eblbackendname.c @@ -0,0 +1,28 @@ +/* Return backend name. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_backend_name (ebl) + Ebl *ebl; +{ + return ebl != NULL ? ebl->emulation : gettext ("No backend"); +} diff --git a/libebl/eblclosebackend.c b/libebl/eblclosebackend.c new file mode 100644 index 00000000..c5579612 --- /dev/null +++ b/libebl/eblclosebackend.c @@ -0,0 +1,39 @@ +/* Free ELF backend handle. + 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. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <dlfcn.h> +#include <stdlib.h> + +#include <libeblP.h> + + +void +ebl_closebackend (Ebl *ebl) +{ + if (ebl != NULL) + { + /* Run the destructor. */ + ebl->destr (ebl); + + /* Close the dynamically loaded object. */ + if (ebl->dlhandle != NULL) + (void) dlclose (ebl->dlhandle); + + /* Free the resources. */ + free (ebl); + } +} diff --git a/libebl/eblcopyrelocp.c b/libebl/eblcopyrelocp.c new file mode 100644 index 00000000..2d3362a2 --- /dev/null +++ b/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/libebl/eblcorenote.c b/libebl/eblcorenote.c new file mode 100644 index 00000000..725d3a1b --- /dev/null +++ b/libebl/eblcorenote.c @@ -0,0 +1,191 @@ +/* Print contents of core note. + 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 + 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 <byteswap.h> +#include <endian.h> +#include <inttypes.h> +#include <stdio.h> +#include <stddef.h> +#include <libeblP.h> + + +void +ebl_core_note (ebl, name, type, descsz, desc) + Ebl *ebl; + const char *name; + uint32_t type; + uint32_t descsz; + const char *desc; +{ + 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. */ + switch (type) + { + case NT_PLATFORM: + printf (gettext (" Platform: %.*s\n"), (int) descsz, desc); + break; + + case NT_AUXV: + ; + size_t elsize = (class == ELFCLASS32 + ? sizeof (Elf32_auxv_t) : sizeof (Elf64_auxv_t)); + + for (size_t cnt = 0; (cnt + 1) * elsize <= descsz; ++cnt) + { + uintmax_t atype; + uintmax_t val; + + if (class == ELFCLASS32) + { + Elf32_auxv_t *auxv = &((Elf32_auxv_t *) desc)[cnt]; + + 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]; + + 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 + else? If yes, move code into a separate function. */ + const char *at; + + switch (atype) + { +#define NEW_AT(name) case AT_##name: at = #name; break + NEW_AT (NULL); + NEW_AT (IGNORE); + NEW_AT (EXECFD); + NEW_AT (PHDR); + NEW_AT (PHENT); + NEW_AT (PHNUM); + NEW_AT (PAGESZ); + NEW_AT (BASE); + NEW_AT (FLAGS); + NEW_AT (ENTRY); + NEW_AT (NOTELF); + NEW_AT (UID); + NEW_AT (EUID); + NEW_AT (GID); + NEW_AT (EGID); + NEW_AT (CLKTCK); + NEW_AT (PLATFORM); + NEW_AT (HWCAP); + NEW_AT (FPUCW); + NEW_AT (DCACHEBSIZE); + NEW_AT (ICACHEBSIZE); + NEW_AT (UCACHEBSIZE); + NEW_AT (IGNOREPPC); + NEW_AT (SECURE); + 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; + } + + switch (atype) + { + case AT_NULL: + case AT_IGNORE: + case AT_IGNOREPPC: + case AT_NOTELF: + default: + printf (" %s\n", at); + break; + + case AT_EXECFD: + case AT_PHENT: + case AT_PHNUM: + case AT_PAGESZ: + case AT_UID: + case AT_EUID: + case AT_GID: + case AT_EGID: + case AT_CLKTCK: + case AT_FPUCW: + case AT_DCACHEBSIZE: + case AT_ICACHEBSIZE: + case AT_UCACHEBSIZE: + case AT_SECURE: + 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: + case AT_BASE: + case AT_FLAGS: /* XXX Print flags? */ + case AT_ENTRY: + case AT_PLATFORM: /* XXX Get string? */ + case AT_HWCAP: /* XXX Print flags? */ + case AT_SYSINFO: + case AT_SYSINFO_EHDR: + printf (" %s: %#jx\n", at, val); + break; + } + + if (atype == AT_NULL) + /* Reached the end. */ + break; + } + break; + + default: + /* Unknown type. */ + break; + } +} diff --git a/libebl/eblcorenotetypename.c b/libebl/eblcorenotetypename.c new file mode 100644 index 00000000..4a94d2ba --- /dev/null +++ b/libebl/eblcorenotetypename.c @@ -0,0 +1,68 @@ +/* Return note type name. + Copyright (C) 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_core_note_type_name (ebl, type, buf, len) + Ebl *ebl; + uint32_t type; + char *buf; + size_t len; +{ + const char *res = ebl->core_note_type_name (type, buf, len); + + if (res == NULL) + { + static const char *knowntypes[] = + { +#define KNOWNSTYPE(name) [NT_##name] = #name + KNOWNSTYPE (PRSTATUS), + KNOWNSTYPE (FPREGSET), + KNOWNSTYPE (PRPSINFO), + KNOWNSTYPE (TASKSTRUCT), + KNOWNSTYPE (PLATFORM), + KNOWNSTYPE (AUXV), + KNOWNSTYPE (GWINDOWS), + KNOWNSTYPE (ASRS), + KNOWNSTYPE (PSTATUS), + KNOWNSTYPE (PSINFO), + KNOWNSTYPE (PRCRED), + KNOWNSTYPE (UTSNAME), + KNOWNSTYPE (LWPSTATUS), + KNOWNSTYPE (LWPSINFO), + KNOWNSTYPE (PRFPXREG) + }; + + /* Handle standard names. */ + if (type < sizeof (knowntypes) / sizeof (knowntypes[0]) + && knowntypes[type] != NULL) + res = knowntypes[type]; + else + { + snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type); + + res = buf; + } + } + + return res; +} diff --git a/libebl/ebldebugscnp.c b/libebl/ebldebugscnp.c new file mode 100644 index 00000000..59310b51 --- /dev/null +++ b/libebl/ebldebugscnp.c @@ -0,0 +1,29 @@ +/* Check section name for being that of a debug informatino section. + Copyright (C) 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <stdint.h> +#include <libeblP.h> + + +bool +ebl_debugscn_p (ebl, name) + Ebl *ebl; + const char *name; +{ + return ebl->debugscn_p (name); +} diff --git a/libebl/ebldynamictagcheck.c b/libebl/ebldynamictagcheck.c new file mode 100644 index 00000000..68b41691 --- /dev/null +++ b/libebl/ebldynamictagcheck.c @@ -0,0 +1,41 @@ +/* Check dynamic tag. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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_dynamic_tag_check (ebl, tag) + Ebl *ebl; + int64_t tag; +{ + bool res = ebl != NULL ? ebl->dynamic_tag_check (tag) : false; + + if (!res + && ((tag >= 0 && tag < DT_NUM) + || (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT) + || (tag >= DT_GNU_CONFLICT && tag <= DT_SYMINFO) + || tag == DT_VERSYM + || (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM) + || tag == DT_AUXILIARY + || tag == DT_FILTER)) + res = true; + + return res; +} diff --git a/libebl/ebldynamictagname.c b/libebl/ebldynamictagname.c new file mode 100644 index 00000000..464c1e2a --- /dev/null +++ b/libebl/ebldynamictagname.c @@ -0,0 +1,97 @@ +/* Return dynamic tag name. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_dynamic_tag_name (ebl, tag, buf, len) + Ebl *ebl; + int64_t tag; + char *buf; + size_t len; +{ + const char *res = ebl != NULL ? ebl->dynamic_tag_name (tag, buf, len) : NULL; + + if (res == NULL) + { + if (tag >= 0 && tag < DT_NUM) + { + static const char *stdtags[] = + { + "NULL", "NEEDED", "PLTRELSZ", "PLTGOT", "HASH", "STRTAB", + "SYMTAB", "RELA", "RELASZ", "RELAENT", "STRSZ", "SYMENT", + "INIT", "FINI", "SONAME", "RPATH", "SYMBOLIC", "REL", "RELSZ", + "RELENT", "PLTREL", "DEBUG", "TEXTREL", "JMPREL", "BIND_NOW", + "INIT_ARRAY", "FINI_ARRAY", "INIT_ARRAYSZ", "FINI_ARRAYSZ", + "RUNPATH", "FLAGS", "ENCODING", "PREINIT_ARRAY", + "PREINIT_ARRAYSZ" + }; + + res = stdtags[tag]; + } + else if (tag == DT_VERSYM) + res = "VERSYM"; + else if (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT) + { + static const char *valrntags[] = + { + "GNU_PRELINKED", "GNU_CONFLICTSZ", "GNU_LIBLISTSZ", + "CHECKSUM", "PLTPADSZ", "MOVEENT", "MOVESZ", "FEATURE_1", + "POSFLAG_1", "SYMINSZ", "SYMINENT" + }; + + res = valrntags[tag - DT_GNU_PRELINKED]; + } + else if (tag >= DT_GNU_CONFLICT && tag <= DT_SYMINFO) + { + static const char *addrrntags[] = + { + "GNU_CONFLICT", "GNU_LIBLIST", "CONFIG", "DEPAUDIT", "AUDIT", + "PLTPAD", "MOVETAB", "SYMINFO" + }; + + res = addrrntags[tag - DT_GNU_CONFLICT]; + } + else if (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM) + { + static const char *suntags[] = + { + "RELACOUNT", "RELCOUNT", "FLAGS_1", "VERDEF", "VERDEFNUM", + "VERNEED", "VERNEEDNUM" + }; + + res = suntags[tag - DT_RELACOUNT]; + } + else if (tag == DT_AUXILIARY) + res = "AUXILIARY"; + else if (tag == DT_FILTER) + res = "FILTER"; + else + { + snprintf (buf, len, gettext ("<unknown>: %" PRId64), tag); + + res = buf; + + } + } + + return res; +} diff --git a/libebl/eblgotpcreloccheck.c b/libebl/eblgotpcreloccheck.c new file mode 100644 index 00000000..8ae8b7b8 --- /dev/null +++ b/libebl/eblgotpcreloccheck.c @@ -0,0 +1,29 @@ +/* Return true if the symbol type is that referencing the GOT. E.g., + R_386_GOTPC. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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_gotpc_reloc_check (ebl, reloc) + Ebl *ebl; + int reloc; +{ + return ebl != NULL ? ebl->gotpc_reloc_check (ebl->elf, reloc) : false; +} diff --git a/libebl/eblgstrtab.c b/libebl/eblgstrtab.c new file mode 100644 index 00000000..57cb2d8f --- /dev/null +++ b/libebl/eblgstrtab.c @@ -0,0 +1,350 @@ +/* Generic string table 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 <assert.h> +#include <inttypes.h> +#include <libelf.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#include "libebl.h" + +#ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + + +struct Ebl_GStrent +{ + const char *string; + size_t len; + struct Ebl_GStrent *next; + struct Ebl_GStrent *left; + struct Ebl_GStrent *right; + size_t offset; + unsigned int width; + char reverse[0]; +}; + + +struct memoryblock +{ + struct memoryblock *next; + char memory[0]; +}; + + +struct Ebl_GStrtab +{ + struct Ebl_GStrent *root; + struct memoryblock *memory; + char *backp; + size_t left; + size_t total; + unsigned int width; + bool nullstr; + + struct Ebl_GStrent null; +}; + + +/* Cache for the pagesize. We correct this value a bit so that `malloc' + is not allocating more than a page. */ +static size_t ps; + + +struct Ebl_GStrtab * +ebl_gstrtabinit (unsigned int width, bool nullstr) +{ + struct Ebl_GStrtab *ret; + + if (ps == 0) + { + ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *); + assert (sizeof (struct memoryblock) < ps); + } + + ret = (struct Ebl_GStrtab *) calloc (1, sizeof (struct Ebl_GStrtab)); + if (ret != NULL) + { + ret->width = width; + ret->nullstr = nullstr; + + if (nullstr) + { + ret->null.len = 1; + ret->null.string = (char *) calloc (1, width); + } + } + + return ret; +} + + +static void +morememory (struct Ebl_GStrtab *st, size_t len) +{ + struct memoryblock *newmem; + + if (len < ps) + len = ps; + newmem = (struct memoryblock *) malloc (len); + if (newmem == NULL) + abort (); + + newmem->next = st->memory; + st->memory = newmem; + st->backp = newmem->memory; + st->left = len - offsetof (struct memoryblock, memory); +} + + +void +ebl_gstrtabfree (struct Ebl_GStrtab *st) +{ + struct memoryblock *mb = st->memory; + + while (mb != NULL) + { + void *old = mb; + mb = mb->next; + free (old); + } + + if (st->null.string != NULL) + free ((char *) st->null.string); + + free (st); +} + + +static struct Ebl_GStrent * +newstring (struct Ebl_GStrtab *st, const char *str, size_t len) +{ + /* Compute the amount of padding needed to make the structure aligned. */ + size_t align = ((__alignof__ (struct Ebl_GStrent) + - (((uintptr_t) st->backp) + & (__alignof__ (struct Ebl_GStrent) - 1))) + & (__alignof__ (struct Ebl_GStrent) - 1)); + + /* Make sure there is enough room in the memory block. */ + if (st->left < align + sizeof (struct Ebl_GStrent) + len * st->width) + { + morememory (st, sizeof (struct Ebl_GStrent) + len * st->width); + align = 0; + } + + /* Create the reserved string. */ + struct Ebl_GStrent *newstr = (struct Ebl_GStrent *) (st->backp + align); + newstr->string = str; + newstr->len = len; + newstr->width = st->width; + newstr->next = NULL; + newstr->left = NULL; + newstr->right = NULL; + newstr->offset = 0; + for (int i = len - 2; i >= 0; --i) + for (int j = st->width - 1; j >= 0; --j) + newstr->reverse[i * st->width + j] = str[(len - 2 - i) * st->width + j]; + for (size_t j = 0; j < st->width; ++j) + newstr->reverse[(len - 1) * st->width + j] = '\0'; + st->backp += align + sizeof (struct Ebl_GStrent) + len * st->width; + st->left -= align + sizeof (struct Ebl_GStrent) + len * st->width; + + return newstr; +} + + +/* XXX This function should definitely be rewritten to use a balancing + tree algorith (AVL, red-black trees). For now a simple, correct + implementation is enough. */ +static struct Ebl_GStrent ** +searchstring (struct Ebl_GStrent **sep, struct Ebl_GStrent *newstr) +{ + int cmpres; + + /* More strings? */ + if (*sep == NULL) + { + *sep = newstr; + return sep; + } + + /* Compare the strings. */ + cmpres = memcmp ((*sep)->reverse, newstr->reverse, + (MIN ((*sep)->len, newstr->len) - 1) * (*sep)->width); + if (cmpres == 0) + /* We found a matching string. */ + return sep; + else if (cmpres > 0) + return searchstring (&(*sep)->left, newstr); + else + return searchstring (&(*sep)->right, newstr); +} + + +/* Add new string. The actual string is assumed to be permanent. */ +struct Ebl_GStrent * +ebl_gstrtabadd (struct Ebl_GStrtab *st, const char *str, size_t len) +{ + struct Ebl_GStrent *newstr; + struct Ebl_GStrent **sep; + + /* Compute the string length if the caller doesn't know it. */ + if (len == 0) + { + size_t j; + + do + for (j = 0; j < st->width; ++j) + if (str[len * st->width + j] != '\0') + break; + while (j == st->width && ++len); + } + + /* Make sure all "" strings get offset 0 but only if the table was + created with a special null entry in mind. */ + if (len == 1 && st->null.string != NULL) + return &st->null; + + /* Allocate memory for the new string and its associated information. */ + newstr = newstring (st, str, len); + + /* Search in the array for the place to insert the string. If there + is no string with matching prefix and no string with matching + leading substring, create a new entry. */ + sep = searchstring (&st->root, newstr); + if (*sep != newstr) + { + /* This is not the same entry. This means we have a prefix match. */ + if ((*sep)->len > newstr->len) + { + struct Ebl_GStrent *subs; + + /* Check whether we already know this string. */ + for (subs = (*sep)->next; subs != NULL; subs = subs->next) + if (subs->len == newstr->len) + { + /* We have an exact match with a substring. Free the memory + we allocated. */ + st->left += (st->backp - (char *) newstr) * st->width; + st->backp = (char *) newstr; + + return subs; + } + + /* We have a new substring. This means we don't need the reverse + string of this entry anymore. */ + st->backp -= newstr->len; + st->left += newstr->len; + + newstr->next = (*sep)->next; + (*sep)->next = newstr; + } + else if ((*sep)->len != newstr->len) + { + /* When we get here it means that the string we are about to + add has a common prefix with a string we already have but + it is longer. In this case we have to put it first. */ + st->total += newstr->len - (*sep)->len; + newstr->next = *sep; + newstr->left = (*sep)->left; + newstr->right = (*sep)->right; + *sep = newstr; + } + else + { + /* We have an exact match. Free the memory we allocated. */ + st->left += (st->backp - (char *) newstr) * st->width; + st->backp = (char *) newstr; + + newstr = *sep; + } + } + else + st->total += newstr->len; + + return newstr; +} + + +static void +copystrings (struct Ebl_GStrent *nodep, char **freep, size_t *offsetp) +{ + struct Ebl_GStrent *subs; + + if (nodep->left != NULL) + copystrings (nodep->left, freep, offsetp); + + /* Process the current node. */ + nodep->offset = *offsetp; + *freep = (char *) mempcpy (*freep, nodep->string, nodep->len * nodep->width); + *offsetp += nodep->len * nodep->width; + + for (subs = nodep->next; subs != NULL; subs = subs->next) + { + assert (subs->len < nodep->len); + subs->offset = nodep->offset + (nodep->len - subs->len) * nodep->width; + assert (subs->offset != 0 || subs->string[0] == '\0'); + } + + if (nodep->right != NULL) + copystrings (nodep->right, freep, offsetp); +} + + +void +ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data) +{ + size_t copylen; + char *endp; + size_t nulllen = st->nullstr ? st->width : 0; + + /* Fill in the information. */ + data->d_buf = malloc (st->total + nulllen); + if (data->d_buf == NULL) + abort (); + + /* The first byte must always be zero if we created the table with a + null string. */ + if (st->nullstr) + memset (data->d_buf, '\0', st->width); + + data->d_type = ELF_T_BYTE; + data->d_size = st->total + nulllen; + data->d_off = 0; + data->d_align = 1; + data->d_version = EV_CURRENT; + + /* Now run through the tree and add all the string while also updating + the offset members of the elfstrent records. */ + endp = (char *) data->d_buf + nulllen; + copylen = nulllen; + copystrings (st->root, &endp, ©len); + assert (copylen == st->total * st->width + nulllen); +} + + +size_t +ebl_gstrtaboffset (struct Ebl_GStrent *se) +{ + return se->offset; +} diff --git a/libebl/eblmachineflagcheck.c b/libebl/eblmachineflagcheck.c new file mode 100644 index 00000000..abc8d302 --- /dev/null +++ b/libebl/eblmachineflagcheck.c @@ -0,0 +1,28 @@ +/* Check machine flag. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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_machine_flag_check (ebl, flags) + Ebl *ebl; + Elf64_Word flags; +{ + return ebl != NULL ? ebl->machine_flag_check (flags) : (flags == 0); +} diff --git a/libebl/eblmachineflagname.c b/libebl/eblmachineflagname.c new file mode 100644 index 00000000..228a9945 --- /dev/null +++ b/libebl/eblmachineflagname.c @@ -0,0 +1,76 @@ +/* Return machine flag names. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <string.h> +#include <libeblP.h> + + +const char * +ebl_machine_flag_name (ebl, flags, buf, len) + Ebl *ebl; + Elf64_Word flags; + char *buf; + size_t len; +{ + const char *res; + + if (flags == 0) + res = ""; + else + { + char *cp = buf; + int first = 1; + const char *machstr; + size_t machstrlen; + + do + { + if (! first) + { + if (cp + 1 >= buf + len) + break; + *cp++ = ','; + } + + machstr = ebl != NULL ? ebl->machine_flag_name (&flags) : NULL; + if (machstr == NULL) + { + /* No more known flag. */ + snprintf (cp, buf + len - cp, "%#x", flags); + break; + } + + machstrlen = strlen (machstr) + 1; + if ((size_t) (buf + len - cp) < machstrlen) + { + *((char *) mempcpy (cp, machstr, buf + len - cp - 1)) = '\0'; + break; + } + + cp = mempcpy (cp, machstr, machstrlen); + + first = 0; + } + while (flags != 0); + + res = buf; + } + + return res; +} diff --git a/libebl/eblobjecttypename.c b/libebl/eblobjecttypename.c new file mode 100644 index 00000000..c099c71d --- /dev/null +++ b/libebl/eblobjecttypename.c @@ -0,0 +1,48 @@ +/* Return object file type name. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_object_type_name (ebl, object, buf, len) + Ebl *ebl; + int object; + char *buf; + size_t len; +{ + const char *res; + + res = ebl != NULL ? ebl->object_type_name (object, buf, len) : NULL; + if (res == NULL) + { + /* Handle OS-specific section names. */ + if (object >= ET_LOOS && object <= ET_HIOS) + snprintf (buf, len, "LOOS+%x", object - ET_LOOS); + /* Handle processor-specific section names. */ + else if (object >= ET_LOPROC && object <= ET_HIPROC) + snprintf (buf, len, "LOPROC+%x", object - ET_LOPROC); + else + snprintf (buf, len, "%s: %d", gettext ("<unknown>"), object); + + res = buf; + } + + return res; +} diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c new file mode 100644 index 00000000..5adff18e --- /dev/null +++ b/libebl/eblobjnote.c @@ -0,0 +1,87 @@ +/* Print contents of object file note. + Copyright (C) 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <stdio.h> +#include <string.h> +#include <libeblP.h> + + +void +ebl_object_note (ebl, name, type, descsz, desc) + Ebl *ebl; + const char *name; + uint32_t type; + uint32_t descsz; + const char *desc; +{ + if (! ebl->object_note (name, type, descsz, desc)) + /* The machine specific function did not know this type. */ + switch (type) + { + case NT_VERSION: + if (strcmp (name, "GNU") == 0 && descsz >= 8) + { + struct + { + uint32_t os; + uint32_t version[descsz / 4 - 1]; + } *tag = (__typeof (tag)) desc; + + const char *os; + switch (tag->os) + { + case ELF_NOTE_OS_LINUX: + os = "Linux"; + break; + + case ELF_NOTE_OS_GNU: + os = "GNU"; + break; + + case ELF_NOTE_OS_SOLARIS2: + os = "Solaris"; + break; + + case ELF_NOTE_OS_FREEBSD: + os = "FreeBSD"; + break; + + default: + os = "???"; + break; + } + + printf (gettext (" OS: %s, ABI: "), os); + size_t cnt; + for (cnt = 0; cnt < descsz / 4 - 1; ++cnt) + { + if (cnt != 0) + putchar_unlocked ('.'); + printf ("%" PRIu32, tag->version[cnt]); + } + putchar_unlocked ('\n'); + break; + } + /* FALLTHROUGH */ + + default: + /* Unknown type. */ + break; + } +} diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c new file mode 100644 index 00000000..a963cefb --- /dev/null +++ b/libebl/eblobjnotetypename.c @@ -0,0 +1,54 @@ +/* Return note type name. + Copyright (C) 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_object_note_type_name (ebl, type, buf, len) + Ebl *ebl; + uint32_t type; + char *buf; + size_t len; +{ + const char *res = ebl->object_note_type_name (type, buf, len); + + if (res == NULL) + { + static const char *knowntypes[] = + { +#define KNOWNSTYPE(name) [NT_##name] = #name + KNOWNSTYPE (VERSION), + }; + + /* Handle standard names. */ + if (type < sizeof (knowntypes) / sizeof (knowntypes[0]) + && knowntypes[type] != NULL) + res = knowntypes[type]; + else + { + snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c new file mode 100644 index 00000000..dc2f7c30 --- /dev/null +++ b/libebl/eblopenbackend.c @@ -0,0 +1,551 @@ +/* Generate ELF backend handle. + Copyright (C) 2000, 2001, 2002, 2003, 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 + 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 <dlfcn.h> +#include <error.h> +#include <gelf.h> +#include <stdlib.h> +#include <string.h> + +#include <libeblP.h> + + +/* This table should contain the complete list of architectures as far + as the ELF specification is concerned. */ +/* XXX When things are stable replace the string pointers with char + arrays to avoid relocations. */ +static const struct +{ + const char *dsoname; + const char *emulation; + const char *prefix; + int prefix_len; + int em; +} 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 }, +}; +#define nmachines (sizeof (machines) / sizeof (machines[0])) + + +/* Default callbacks. Mostly they just return the error value. */ +static const char *default_object_type_name (int ignore, char *buf, + size_t len); +static const char *default_reloc_type_name (int ignore, char *buf, size_t len); +static bool default_reloc_type_check (int ignore); +static bool default_reloc_valid_use (Elf *elf, int ignore); +static Elf_Type default_reloc_simple_type (Elf *elf, int ignore); +static bool default_gotpc_reloc_check (Elf *elf, int ignore); +static const char *default_segment_type_name (int ignore, char *buf, + size_t len); +static const char *default_section_type_name (int ignore, char *buf, + size_t len); +static const char *default_section_name (int ignore, int ignore2, char *buf, + size_t len); +static const char *default_machine_flag_name (Elf64_Word *ignore); +static bool default_machine_flag_check (Elf64_Word flags); +static const char *default_symbol_type_name (int ignore, char *buf, + size_t len); +static const char *default_symbol_binding_name (int ignore, char *buf, + size_t len); +static const char *default_dynamic_tag_name (int64_t ignore, char *buf, + size_t len); +static bool default_dynamic_tag_check (int64_t ignore); +static GElf_Word default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2); +static const char *default_osabi_name (int ignore, char *buf, size_t len); +static void default_destr (struct ebl *ignore); +static const char *default_core_note_type_name (uint32_t, char *buf, + size_t len); +static const char *default_object_note_type_name (uint32_t, char *buf, + size_t len); +static bool default_core_note (const char *name, uint32_t type, + uint32_t descsz, const char *desc); +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 void +fill_defaults (Ebl *result) +{ + result->object_type_name = default_object_type_name; + result->reloc_type_name = default_reloc_type_name; + result->reloc_type_check = default_reloc_type_check; + result->reloc_valid_use = default_reloc_valid_use; + result->reloc_simple_type = default_reloc_simple_type; + result->gotpc_reloc_check = default_gotpc_reloc_check; + result->segment_type_name = default_segment_type_name; + result->section_type_name = default_section_type_name; + result->section_name = default_section_name; + result->machine_flag_name = default_machine_flag_name; + result->machine_flag_check = default_machine_flag_check; + result->symbol_type_name = default_symbol_type_name; + result->symbol_binding_name = default_symbol_binding_name; + result->dynamic_tag_name = default_dynamic_tag_name; + result->dynamic_tag_check = default_dynamic_tag_check; + result->sh_flags_combine = default_sh_flags_combine; + result->osabi_name = default_osabi_name; + result->core_note_type_name = default_core_note_type_name; + result->object_note_type_name = default_object_note_type_name; + 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->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 + DSO name we try to load the appropriate module to handle this + binary type. + + Multiple modules for the same machine type are possible and they + will be tried in sequence. The lookup process will only stop + when a module which can handle the machine type is found or all + available matching modules are tried. */ + for (cnt = 0; cnt < nmachines; ++cnt) + if ((emulation != NULL && strcmp (emulation, machines[cnt].emulation) == 0) + || (emulation == NULL && machines[cnt].em == machine)) + { + /* Well, we know the emulation name now. */ + result->emulation = machines[cnt].emulation; + +#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, ORIGINDIR "libebl_"), + machines[cnt].dsoname), + ".so"); + + void *h = dlopen (dsoname, RTLD_LAZY); + if (h == NULL) + { + strcpy (stpcpy (stpcpy (dsoname, "libebl_"), + machines[cnt].dsoname), + ".so"); + h = dlopen (dsoname, RTLD_LAZY); + } + + /* Try without an explicit path. */ + if (h != NULL) + { + /* 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"]; + + strcpy (mempcpy (symname, machines[cnt].prefix, + machines[cnt].prefix_len), "_init"); + + initp = (ebl_bhinit_t) dlsym (h, symname); + if (initp != NULL + && (modversion = initp (elf, machine, result, sizeof (Ebl))) + && strcmp (version, modversion) == 0) + { + /* We found a module to handle our file. */ + result->dlhandle = h; + result->elf = elf; + + /* A few entries are mandatory. */ + assert (result->name != NULL); + assert (result->destr != NULL); + + return result; + } + + /* Not the module we need. */ + (void) dlclose (h); + } + + /* We cannot find a DSO but the emulation/machine ID matches. + Return that information. */ + result->dlhandle = NULL; + result->elf = elf; + result->name = machines[cnt].prefix; + fill_defaults (result); + + return result; + } + + /* Nothing matched. We use only the default callbacks. */ + result->dlhandle = NULL; + result->elf = elf; + result->emulation = "<unknown>"; + result->name = "<unknown>"; + fill_defaults (result); + + return result; +} + + +/* Find an appropriate backend for the file associated with ELF. */ +Ebl * +ebl_openbackend (elf) + Elf *elf; +{ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + + /* Get the ELF header of the object. */ + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + // XXX uncomment + // __libebl_seterror (elf_errno ()); + return NULL; + } + + return openbackend (elf, NULL, ehdr->e_machine); +} + + +/* Find backend without underlying ELF file. */ +Ebl * +ebl_openbackend_machine (machine) + GElf_Half machine; +{ + return openbackend (NULL, NULL, machine); +} + + +/* Find backend with given emulation name. */ +Ebl * +ebl_openbackend_emulation (const char *emulation) +{ + return openbackend (NULL, emulation, EM_NONE); +} + + +/* Default callbacks. Mostly they just return the error value. */ +static const char * +default_object_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_reloc_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_reloc_type_check (int ignore __attribute__ ((unused))) +{ + return false; +} + +static bool +default_reloc_valid_use (Elf *elf __attribute__ ((unused)), + int ignore __attribute__ ((unused))) +{ + return false; +} + +static Elf_Type +default_reloc_simple_type (Elf *elf __attribute__ ((unused)), + int ignore __attribute__ ((unused))) +{ + return ELF_T_NUM; +} + +static bool +default_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), + int ignore __attribute__ ((unused))) +{ + return false; +} + +static const char * +default_segment_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_section_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_section_name (int ignore __attribute__ ((unused)), + int ignore2 __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_machine_flag_name (Elf64_Word *ignore __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_machine_flag_check (Elf64_Word flags __attribute__ ((unused))) +{ + return flags == 0; +} + +static const char * +default_symbol_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_symbol_binding_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_dynamic_tag_name (int64_t ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_dynamic_tag_check (int64_t ignore __attribute__ ((unused))) +{ + return false; +} + +static GElf_Word +default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2) +{ + return SH_FLAGS_COMBINE (flags1, flags2); +} + +static void +default_destr (struct ebl *ignore __attribute__ ((unused))) +{ +} + +static const char * +default_osabi_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_core_note_type_name (uint32_t ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_object_note_type_name (uint32_t ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_core_note (const char *name __attribute__ ((unused)), + uint32_t type __attribute__ ((unused)), + uint32_t descsz __attribute__ ((unused)), + const char *desc __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_object_note (const char *name __attribute__ ((unused)), + uint32_t type __attribute__ ((unused)), + uint32_t descsz __attribute__ ((unused)), + const char *desc __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_debugscn_p (const char *name) +{ + /* We know by default only about the DWARF debug sections which have + fixed names. */ + static const char *dwarf_scn_names[] = + { + /* DWARF 1 */ + ".debug", + ".line", + /* GNU DWARF 1 extensions */ + ".debug_srcinfo", + ".debug_sfnames", + /* DWARF 1.1 and DWARF 2 */ + ".debug_aranges", + ".debug_pubnames", + /* DWARF 2 */ + ".debug_info", + ".debug_abbrev", + ".debug_line", + ".debug_frame", + ".debug_str", + ".debug_loc", + ".debug_macinfo", + /* DWARF 3 */ + ".debug_ranges", + /* SGI/MIPS DWARF 2 extensions */ + ".debug_weaknames", + ".debug_funcnames", + ".debug_typenames", + ".debug_varnames" + }; + const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names) + / sizeof (dwarf_scn_names[0])); + for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt) + if (strcmp (name, dwarf_scn_names[cnt]) == 0) + return true; + + return false; +} + +static bool +default_copy_reloc_p (int reloc __attribute__ ((unused))) +{ + return false; +} diff --git a/libebl/eblosabiname.c b/libebl/eblosabiname.c new file mode 100644 index 00000000..9a1e6534 --- /dev/null +++ b/libebl/eblosabiname.c @@ -0,0 +1,69 @@ +/* Return OS ABI name + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_osabi_name (ebl, osabi, buf, len) + Ebl *ebl; + int osabi; + char *buf; + size_t len; +{ + const char *res = ebl != NULL ? ebl->osabi_name (osabi, buf, len) : NULL; + + if (res == NULL) + { + if (osabi == ELFOSABI_NONE) + res = "UNIX - System V"; + else if (osabi == ELFOSABI_HPUX) + res = "HP/UX"; + else if (osabi == ELFOSABI_NETBSD) + res = "NetBSD"; + else if (osabi == ELFOSABI_LINUX) + res = "Linux"; + else if (osabi == ELFOSABI_SOLARIS) + res = "Solaris"; + else if (osabi == ELFOSABI_AIX) + res = "AIX"; + else if (osabi == ELFOSABI_IRIX) + res = "Irix"; + else if (osabi == ELFOSABI_FREEBSD) + res = "FreeBSD"; + else if (osabi == ELFOSABI_TRU64) + res = "TRU64"; + else if (osabi == ELFOSABI_MODESTO) + res = "Modesto"; + else if (osabi == ELFOSABI_OPENBSD) + res = "OpenBSD"; + else if (osabi == ELFOSABI_ARM) + res = "Arm"; + else if (osabi == ELFOSABI_STANDALONE) + res = gettext ("Stand alone"); + else + { + snprintf (buf, len, "%s: %d", gettext ("<unknown>"), osabi); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblrelocsimpletype.c b/libebl/eblrelocsimpletype.c new file mode 100644 index 00000000..3e048d1f --- /dev/null +++ b/libebl/eblrelocsimpletype.c @@ -0,0 +1,27 @@ +/* Check relocation type for simple types. + 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 <libeblP.h> + + +Elf_Type +ebl_reloc_simple_type (ebl, reloc) + Ebl *ebl; + int reloc; +{ + return ebl != NULL ? ebl->reloc_simple_type (ebl->elf, reloc) : ELF_T_NUM; +} diff --git a/libebl/eblreloctypecheck.c b/libebl/eblreloctypecheck.c new file mode 100644 index 00000000..cafbc611 --- /dev/null +++ b/libebl/eblreloctypecheck.c @@ -0,0 +1,28 @@ +/* Check relocation type. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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_reloc_type_check (ebl, reloc) + Ebl *ebl; + int reloc; +{ + return ebl != NULL ? ebl->reloc_type_check (reloc) : false; +} diff --git a/libebl/eblreloctypename.c b/libebl/eblreloctypename.c new file mode 100644 index 00000000..5fa95608 --- /dev/null +++ b/libebl/eblreloctypename.c @@ -0,0 +1,38 @@ +/* Return relocation type name. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_reloc_type_name (ebl, reloc, buf, len) + Ebl *ebl; + int reloc; + char *buf; + size_t len; +{ + const char *res; + + res = ebl != NULL ? ebl->reloc_type_name (reloc, buf, len) : NULL; + if (res == NULL) + /* There are no generic relocation type names. */ + res = "???"; + + return res; +} diff --git a/libebl/eblrelocvaliduse.c b/libebl/eblrelocvaliduse.c new file mode 100644 index 00000000..74889861 --- /dev/null +++ b/libebl/eblrelocvaliduse.c @@ -0,0 +1,28 @@ +/* Check relocation type use. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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_reloc_valid_use (ebl, reloc) + Ebl *ebl; + int reloc; +{ + return ebl != NULL ? ebl->reloc_valid_use (ebl->elf, reloc) : false; +} diff --git a/libebl/eblsectionname.c b/libebl/eblsectionname.c new file mode 100644 index 00000000..6c801db6 --- /dev/null +++ b/libebl/eblsectionname.c @@ -0,0 +1,81 @@ +/* Return section name. + Copyright (C) 2001, 2002, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_section_name (ebl, section, xsection, buf, len, scnnames, shnum) + Ebl *ebl; + int section; + int xsection; + char *buf; + size_t len; + const char *scnnames[]; + size_t shnum; +{ + const char *res = ebl != NULL ? ebl->section_name (section, xsection, + buf, len) : NULL; + + if (res == NULL) + { + if (section == SHN_UNDEF) + res = "UNDEF"; + else if (section == SHN_ABS) + res = "ABS"; + else if (section == SHN_COMMON) + res = "COMMON"; + else if (section == SHN_BEFORE) + res = "BEFORE"; + else if (section == SHN_AFTER) + res = "AFTER"; + else if ((section < SHN_LORESERVE || section == SHN_XINDEX) + && (size_t) section < shnum) + { + int idx = section != SHN_XINDEX ? section : xsection; + + if (scnnames != NULL) + res = scnnames[idx]; + else + { + snprintf (buf, len, "%d", idx); + res = buf; + } + } + else + { + /* Handle OS-specific section names. */ + if (section == SHN_XINDEX) + snprintf (buf, len, "%s: %d", "XINDEX", xsection); + else if (section >= SHN_LOOS && section <= SHN_HIOS) + snprintf (buf, len, "LOOS+%x", section - SHN_LOOS); + /* Handle processor-specific section names. */ + else if (section >= SHN_LOPROC && section <= SHN_HIPROC) + snprintf (buf, len, "LOPROC+%x", section - SHN_LOPROC); + else if (section >= SHN_LORESERVE && section <= SHN_HIRESERVE) + snprintf (buf, len, "LORESERVE+%x", section - SHN_LORESERVE); + else + snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblsectionstripp.c b/libebl/eblsectionstripp.c new file mode 100644 index 00000000..77a22cac --- /dev/null +++ b/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/libebl/eblsectiontypename.c b/libebl/eblsectiontypename.c new file mode 100644 index 00000000..e6857acd --- /dev/null +++ b/libebl/eblsectiontypename.c @@ -0,0 +1,103 @@ +/* Return section type name. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_section_type_name (ebl, section, buf, len) + Ebl *ebl; + int section; + char *buf; + size_t len; +{ + const char *res = ebl->section_type_name (section, buf, len); + + if (res == NULL) + { + static const char *knowntypes[] = + { +#define KNOWNSTYPE(name) [SHT_##name] = #name + KNOWNSTYPE (NULL), + KNOWNSTYPE (PROGBITS), + KNOWNSTYPE (SYMTAB), + KNOWNSTYPE (STRTAB), + KNOWNSTYPE (RELA), + KNOWNSTYPE (HASH), + KNOWNSTYPE (DYNAMIC), + KNOWNSTYPE (NOTE), + KNOWNSTYPE (NOBITS), + KNOWNSTYPE (REL), + KNOWNSTYPE (SHLIB), + KNOWNSTYPE (DYNSYM), + KNOWNSTYPE (INIT_ARRAY), + KNOWNSTYPE (FINI_ARRAY), + KNOWNSTYPE (PREINIT_ARRAY), + KNOWNSTYPE (GROUP), + KNOWNSTYPE (SYMTAB_SHNDX) + }; + + /* Handle standard names. */ + if ((size_t) section < sizeof (knowntypes) / sizeof (knowntypes[0]) + && knowntypes[section] != NULL) + res = knowntypes[section]; + /* The symbol versioning/Sun extensions. */ + else if (section >= SHT_LOSUNW && section <= SHT_HISUNW) + { + static const char *sunwtypes[] = + { +#undef KNOWNSTYPE +#define KNOWNSTYPE(name) [SHT_##name - SHT_LOSUNW] = #name + KNOWNSTYPE (SUNW_move), + KNOWNSTYPE (SUNW_COMDAT), + KNOWNSTYPE (SUNW_syminfo), + KNOWNSTYPE (GNU_verdef), + KNOWNSTYPE (GNU_verneed), + KNOWNSTYPE (GNU_versym) + }; + res = sunwtypes[section - SHT_LOSUNW]; + } + else + { + /* A few GNU additions. */ + if (section == SHT_CHECKSUM) + res = "CHECKSUM"; + else if (section == SHT_GNU_LIBLIST) + res = "GNU_LIBLIST"; + /* Handle OS-specific section names. */ + else + { + if (section >= SHT_LOOS && section <= SHT_HIOS) + snprintf (buf, len, "SHT_LOOS+%x", section - SHT_LOOS); + /* Handle processor-specific section names. */ + else if (section >= SHT_LOPROC && section <= SHT_HIPROC) + snprintf (buf, len, "SHT_LOPROC+%x", section - SHT_LOPROC); + else if ((unsigned int) section >= SHT_LOUSER + && (unsigned int) section <= SHT_HIUSER) + snprintf (buf, len, "SHT_LOUSER+%x", section - SHT_LOUSER); + else + snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section); + + res = buf; + } + } + } + + return res; +} diff --git a/libebl/eblsegmenttypename.c b/libebl/eblsegmenttypename.c new file mode 100644 index 00000000..c59f037d --- /dev/null +++ b/libebl/eblsegmenttypename.c @@ -0,0 +1,75 @@ +/* Return segment type name. + Copyright (C) 2001, 2002, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_segment_type_name (ebl, segment, buf, len) + Ebl *ebl; + int segment; + char *buf; + size_t len; +{ + const char *res; + + res = ebl != NULL ? ebl->segment_type_name (segment, buf, len) : NULL; + if (res == NULL) + { + static const char *ptypes[PT_NUM] = + { +#define PTYPE(name) [PT_##name] = #name + PTYPE (NULL), + PTYPE (LOAD), + PTYPE (DYNAMIC), + PTYPE (INTERP), + PTYPE (NOTE), + PTYPE (SHLIB), + PTYPE (PHDR), + PTYPE (TLS) + }; + + /* Is it one of the standard segment types? */ + if (segment >= PT_NULL && segment < PT_NUM) + res = ptypes[segment]; + else if (segment == PT_GNU_EH_FRAME) + res = "GNU_EH_FRAME"; + else if (segment == PT_GNU_STACK) + res = "GNU_STACK"; + else if (segment == PT_GNU_RELRO) + res = "GNU_RELRO"; + else if (segment == PT_SUNWBSS) + res = "SUNWBSS"; + else if (segment == PT_SUNWSTACK) + res = "SUNWSTACK"; + else + { + if (segment >= PT_LOOS && segment <= PT_HIOS) + snprintf (buf, len, "LOOS+%d", segment - PT_LOOS); + else if (segment >= PT_LOPROC && segment <= PT_HIPROC) + snprintf (buf, len, "LOPROC+%d", segment - PT_LOPROC); + else + snprintf (buf, len, "%s: %d", gettext ("<unknown>"), segment); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblshflagscombine.c b/libebl/eblshflagscombine.c new file mode 100644 index 00000000..7edcf4e7 --- /dev/null +++ b/libebl/eblshflagscombine.c @@ -0,0 +1,29 @@ +/* Return combines section header flags value. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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> + + +GElf_Word +ebl_sh_flags_combine (ebl, flags1, flags2) + Ebl *ebl; + GElf_Word flags1; + GElf_Word flags2; +{ + return ebl->sh_flags_combine (flags1, flags2); +} diff --git a/libebl/eblstrtab.c b/libebl/eblstrtab.c new file mode 100644 index 00000000..165909f4 --- /dev/null +++ b/libebl/eblstrtab.c @@ -0,0 +1,337 @@ +/* ELF string table 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 <assert.h> +#include <inttypes.h> +#include <libelf.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#include "libebl.h" +#include <system.h> + +#ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + + +struct Ebl_Strent +{ + const char *string; + size_t len; + struct Ebl_Strent *next; + struct Ebl_Strent *left; + struct Ebl_Strent *right; + size_t offset; + char reverse[0]; +}; + + +struct memoryblock +{ + struct memoryblock *next; + char memory[0]; +}; + + +struct Ebl_Strtab +{ + struct Ebl_Strent *root; + struct memoryblock *memory; + char *backp; + size_t left; + size_t total; + bool nullstr; + + struct Ebl_Strent null; +}; + + +/* Cache for the pagesize. We correct this value a bit so that `malloc' + is not allocating more than a page. */ +static size_t ps; + + +struct Ebl_Strtab * +ebl_strtabinit (bool nullstr) +{ + if (ps == 0) + { + ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *); + assert (sizeof (struct memoryblock) < ps); + } + + struct Ebl_Strtab *ret + = (struct Ebl_Strtab *) calloc (1, sizeof (struct Ebl_Strtab)); + if (ret != NULL) + { + ret->nullstr = nullstr; + + if (nullstr) + { + ret->null.len = 1; + ret->null.string = ""; + } + } + + return ret; +} + + +static int +morememory (struct Ebl_Strtab *st, size_t len) +{ + if (len < ps) + len = ps; + + struct memoryblock *newmem = (struct memoryblock *) malloc (len); + if (newmem == NULL) + return 1; + + newmem->next = st->memory; + st->memory = newmem; + st->backp = newmem->memory; + st->left = len - offsetof (struct memoryblock, memory); + + return 0; +} + + +void +ebl_strtabfree (struct Ebl_Strtab *st) +{ + struct memoryblock *mb = st->memory; + + while (mb != NULL) + { + void *old = mb; + mb = mb->next; + free (old); + } + + free (st); +} + + +static struct Ebl_Strent * +newstring (struct Ebl_Strtab *st, const char *str, size_t len) +{ + /* Compute the amount of padding needed to make the structure aligned. */ + size_t align = ((__alignof__ (struct Ebl_Strent) + - (((uintptr_t) st->backp) + & (__alignof__ (struct Ebl_Strent) - 1))) + & (__alignof__ (struct Ebl_Strent) - 1)); + + /* Make sure there is enough room in the memory block. */ + if (st->left < align + sizeof (struct Ebl_Strent) + len) + { + if (morememory (st, sizeof (struct Ebl_Strent) + len)) + return NULL; + + align = 0; + } + + /* Create the reserved string. */ + struct Ebl_Strent *newstr = (struct Ebl_Strent *) (st->backp + align); + newstr->string = str; + newstr->len = len; + newstr->next = NULL; + newstr->left = NULL; + newstr->right = NULL; + newstr->offset = 0; + for (int i = len - 2; i >= 0; --i) + newstr->reverse[i] = str[len - 2 - i]; + newstr->reverse[len - 1] = '\0'; + st->backp += align + sizeof (struct Ebl_Strent) + len; + st->left -= align + sizeof (struct Ebl_Strent) + len; + + return newstr; +} + + +/* XXX This function should definitely be rewritten to use a balancing + tree algorith (AVL, red-black trees). For now a simple, correct + implementation is enough. */ +static struct Ebl_Strent ** +searchstring (struct Ebl_Strent **sep, struct Ebl_Strent *newstr) +{ + /* More strings? */ + if (*sep == NULL) + { + *sep = newstr; + return sep; + } + + /* Compare the strings. */ + int cmpres = memcmp ((*sep)->reverse, newstr->reverse, + MIN ((*sep)->len, newstr->len) - 1); + if (cmpres == 0) + /* We found a matching string. */ + return sep; + else if (cmpres > 0) + return searchstring (&(*sep)->left, newstr); + else + return searchstring (&(*sep)->right, newstr); +} + + +/* Add new string. The actual string is assumed to be permanent. */ +struct Ebl_Strent * +ebl_strtabadd (struct Ebl_Strtab *st, const char *str, size_t len) +{ + /* Compute the string length if the caller doesn't know it. */ + if (len == 0) + len = strlen (str) + 1; + + /* Make sure all "" strings get offset 0 but only if the table was + created with a special null entry in mind. */ + if (len == 1 && st->null.string != NULL) + return &st->null; + + /* Allocate memory for the new string and its associated information. */ + struct Ebl_Strent *newstr = newstring (st, str, len); + if (newstr == NULL) + return NULL; + + /* Search in the array for the place to insert the string. If there + is no string with matching prefix and no string with matching + leading substring, create a new entry. */ + struct Ebl_Strent **sep = searchstring (&st->root, newstr); + if (*sep != newstr) + { + /* This is not the same entry. This means we have a prefix match. */ + if ((*sep)->len > newstr->len) + { + /* Check whether we already know this string. */ + for (struct Ebl_Strent *subs = (*sep)->next; subs != NULL; + subs = subs->next) + if (subs->len == newstr->len) + { + /* We have an exact match with a substring. Free the memory + we allocated. */ + st->left += st->backp - (char *) newstr; + st->backp = (char *) newstr; + + return subs; + } + + /* We have a new substring. This means we don't need the reverse + string of this entry anymore. */ + st->backp -= newstr->len; + st->left += newstr->len; + + newstr->next = (*sep)->next; + (*sep)->next = newstr; + } + else if ((*sep)->len != newstr->len) + { + /* When we get here it means that the string we are about to + add has a common prefix with a string we already have but + it is longer. In this case we have to put it first. */ + st->total += newstr->len - (*sep)->len; + newstr->next = *sep; + newstr->left = (*sep)->left; + newstr->right = (*sep)->right; + *sep = newstr; + } + else + { + /* We have an exact match. Free the memory we allocated. */ + st->left += st->backp - (char *) newstr; + st->backp = (char *) newstr; + + newstr = *sep; + } + } + else + st->total += newstr->len; + + return newstr; +} + + +static void +copystrings (struct Ebl_Strent *nodep, char **freep, size_t *offsetp) +{ + if (nodep->left != NULL) + copystrings (nodep->left, freep, offsetp); + + /* Process the current node. */ + nodep->offset = *offsetp; + *freep = (char *) mempcpy (*freep, nodep->string, nodep->len); + *offsetp += nodep->len; + + for (struct Ebl_Strent *subs = nodep->next; subs != NULL; subs = subs->next) + { + assert (subs->len < nodep->len); + subs->offset = nodep->offset + nodep->len - subs->len; + assert (subs->offset != 0 || subs->string[0] == '\0'); + } + + if (nodep->right != NULL) + copystrings (nodep->right, freep, offsetp); +} + + +void +ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data) +{ + size_t nulllen = st->nullstr ? 1 : 0; + + /* Fill in the information. */ + data->d_buf = malloc (st->total + nulllen); + if (data->d_buf == NULL) + abort (); + + /* The first byte must always be zero if we created the table with a + null string. */ + if (st->nullstr) + *((char *) data->d_buf) = '\0'; + + data->d_type = ELF_T_BYTE; + data->d_size = st->total + nulllen; + data->d_off = 0; + data->d_align = 1; + data->d_version = EV_CURRENT; + + /* Now run through the tree and add all the string while also updating + the offset members of the elfstrent records. */ + char *endp = (char *) data->d_buf + nulllen; + size_t copylen = nulllen; + copystrings (st->root, &endp, ©len); + assert (copylen == st->total + nulllen); +} + + +size_t +ebl_strtaboffset (struct Ebl_Strent *se) +{ + return se->offset; +} + + +const char * +ebl_string (struct Ebl_Strent *se) +{ + assert (se->string != NULL); + + return se->string; +} diff --git a/libebl/eblsymbolbindingname.c b/libebl/eblsymbolbindingname.c new file mode 100644 index 00000000..efcd250e --- /dev/null +++ b/libebl/eblsymbolbindingname.c @@ -0,0 +1,57 @@ +/* Return symbol binding name. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_symbol_binding_name (ebl, binding, buf, len) + Ebl *ebl; + int binding; + char *buf; + size_t len; +{ + const char *res; + + res = ebl != NULL ? ebl->symbol_type_name (binding, buf, len) : NULL; + if (res == NULL) + { + static const char *stb_names[STB_NUM] = + { + "LOCAL", "GLOBAL", "WEAK" + }; + + /* Standard binding? */ + if (binding < STB_NUM) + res = stb_names[binding]; + else + { + if (binding >= STB_LOPROC && binding <= STB_HIPROC) + snprintf (buf, len, "LOPROC+%d", binding - STB_LOPROC); + else if (binding >= STB_LOOS && binding <= STB_HIOS) + snprintf (buf, len, "LOOS+%d", binding - STB_LOOS); + else + snprintf (buf, len, gettext ("<unknown>: %d"), binding); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblsymboltypename.c b/libebl/eblsymboltypename.c new file mode 100644 index 00000000..d11aec1a --- /dev/null +++ b/libebl/eblsymboltypename.c @@ -0,0 +1,63 @@ +/* Return symbol type name. + Copyright (C) 2001, 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + 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 <stdio.h> +#include <libeblP.h> + + +const char * +ebl_symbol_type_name (ebl, symbol, buf, len) + Ebl *ebl; + int symbol; + char *buf; + size_t len; +{ + const char *res; + + res = ebl != NULL ? ebl->symbol_type_name (symbol, buf, len) : NULL; + if (res == NULL) + { + static const char *stt_names[STT_NUM] = + { + [STT_NOTYPE] = "NOTYPE", + [STT_OBJECT] = "OBJECT", + [STT_FUNC] = "FUNC", + [STT_SECTION] = "SECTION", + [STT_FILE] = "FILE", + [STT_COMMON] = "COMMON", + [STT_TLS] = "TLS" + }; + + /* Standard type? */ + if (symbol < STT_NUM) + res = stt_names[symbol]; + else + { + if (symbol >= STT_LOPROC && symbol <= STT_HIPROC) + snprintf (buf, len, "LOPROC+%d", symbol - STT_LOPROC); + else if (symbol >= STT_LOOS && symbol <= STT_HIOS) + snprintf (buf, len, "LOOS+%d", symbol - STT_LOOS); + else + snprintf (buf, len, gettext ("<unknown>: %d"), symbol); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblwstrtab.c b/libebl/eblwstrtab.c new file mode 100644 index 00000000..8320cb58 --- /dev/null +++ b/libebl/eblwstrtab.c @@ -0,0 +1,344 @@ +/* ELF string table handling. + Copyright (C) 2000, 2001, 2002 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 <assert.h> +#include <inttypes.h> +#include <libelf.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> +#include <sys/param.h> + +#include "libebl.h" +#include <system.h> + +#ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + + +struct Ebl_WStrent +{ + const wchar_t *string; + size_t len; + struct Ebl_WStrent *next; + struct Ebl_WStrent *left; + struct Ebl_WStrent *right; + size_t offset; + wchar_t reverse[0]; +}; + + +struct memoryblock +{ + struct memoryblock *next; + char memory[0]; +}; + + +struct Ebl_WStrtab +{ + struct Ebl_WStrent *root; + struct memoryblock *memory; + char *backp; + size_t left; + size_t total; + bool nullstr; + + struct Ebl_WStrent null; +}; + + +/* Cache for the pagesize. We correct this value a bit so that `malloc' + is not allocating more than a page. */ +static size_t ps; + + +struct Ebl_WStrtab * +ebl_wstrtabinit (bool nullstr) +{ + struct Ebl_WStrtab *ret; + + if (ps == 0) + { + ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *); + assert (sizeof (struct memoryblock) < ps); + } + + ret = (struct Ebl_WStrtab *) calloc (1, sizeof (struct Ebl_WStrtab)); + if (ret != NULL) + { + ret->nullstr = nullstr; + if (nullstr) + { + ret->null.len = 1; + ret->null.string = L""; + } + } + return ret; +} + + +static int +morememory (struct Ebl_WStrtab *st, size_t len) +{ + struct memoryblock *newmem; + + if (len < ps) + len = ps; + newmem = (struct memoryblock *) malloc (len); + if (newmem == NULL) + return 1; + + newmem->next = st->memory; + st->memory = newmem; + st->backp = newmem->memory; + st->left = len - offsetof (struct memoryblock, memory); + + return 0; +} + + +void +ebl_wstrtabfree (struct Ebl_WStrtab *st) +{ + struct memoryblock *mb = st->memory; + + while (mb != NULL) + { + void *old = mb; + mb = mb->next; + free (old); + } + + free (st); +} + + +static struct Ebl_WStrent * +newstring (struct Ebl_WStrtab *st, const wchar_t *str, size_t len) +{ + struct Ebl_WStrent *newstr; + size_t align; + int i; + + /* Compute the amount of padding needed to make the structure aligned. */ + align = ((__alignof__ (struct Ebl_WStrent) + - (((uintptr_t) st->backp) + & (__alignof__ (struct Ebl_WStrent) - 1))) + & (__alignof__ (struct Ebl_WStrent) - 1)); + + /* Make sure there is enough room in the memory block. */ + if (st->left < align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t)) + { + if (morememory (st, + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t))) + return NULL; + + align = 0; + } + + /* Create the reserved string. */ + newstr = (struct Ebl_WStrent *) (st->backp + align); + newstr->string = str; + newstr->len = len; + newstr->next = NULL; + newstr->left = NULL; + newstr->right = NULL; + newstr->offset = 0; + for (i = len - 2; i >= 0; --i) + newstr->reverse[i] = str[len - 2 - i]; + newstr->reverse[len - 1] = L'\0'; + st->backp += align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t); + st->left -= align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t); + + return newstr; +} + + +/* XXX This function should definitely be rewritten to use a balancing + tree algorith (AVL, red-black trees). For now a simple, correct + implementation is enough. */ +static struct Ebl_WStrent ** +searchstring (struct Ebl_WStrent **sep, struct Ebl_WStrent *newstr) +{ + int cmpres; + + /* More strings? */ + if (*sep == NULL) + { + *sep = newstr; + return sep; + } + + /* Compare the strings. */ + cmpres = wmemcmp ((*sep)->reverse, newstr->reverse, + MIN ((*sep)->len, newstr->len) - 1); + if (cmpres == 0) + /* We found a matching string. */ + return sep; + else if (cmpres > 0) + return searchstring (&(*sep)->left, newstr); + else + return searchstring (&(*sep)->right, newstr); +} + + +/* Add new string. The actual string is assumed to be permanent. */ +struct Ebl_WStrent * +ebl_wstrtabadd (struct Ebl_WStrtab *st, const wchar_t *str, size_t len) +{ + struct Ebl_WStrent *newstr; + struct Ebl_WStrent **sep; + + /* Compute the string length if the caller doesn't know it. */ + if (len == 0) + len = wcslen (str) + 1; + + /* Make sure all "" strings get offset 0 but only if the table was + created with a special null entry in mind. */ + if (len == 1 && st->null.string != NULL) + return &st->null; + + /* Allocate memory for the new string and its associated information. */ + newstr = newstring (st, str, len); + if (newstr == NULL) + return NULL; + + /* Search in the array for the place to insert the string. If there + is no string with matching prefix and no string with matching + leading substring, create a new entry. */ + sep = searchstring (&st->root, newstr); + if (*sep != newstr) + { + /* This is not the same entry. This means we have a prefix match. */ + if ((*sep)->len > newstr->len) + { + struct Ebl_WStrent *subs; + + /* Check whether we already know this string. */ + for (subs = (*sep)->next; subs != NULL; subs = subs->next) + if (subs->len == newstr->len) + { + /* We have an exact match with a substring. Free the memory + we allocated. */ + st->left += st->backp - (char *) newstr; + st->backp = (char *) newstr; + + return subs; + } + + /* We have a new substring. This means we don't need the reverse + string of this entry anymore. */ + st->backp -= newstr->len; + st->left += newstr->len; + + newstr->next = (*sep)->next; + (*sep)->next = newstr; + } + else if ((*sep)->len != newstr->len) + { + /* When we get here it means that the string we are about to + add has a common prefix with a string we already have but + it is longer. In this case we have to put it first. */ + st->total += newstr->len - (*sep)->len; + newstr->next = *sep; + newstr->left = (*sep)->left; + newstr->right = (*sep)->right; + *sep = newstr; + } + else + { + /* We have an exact match. Free the memory we allocated. */ + st->left += st->backp - (char *) newstr; + st->backp = (char *) newstr; + + newstr = *sep; + } + } + else + st->total += newstr->len; + + return newstr; +} + + +static void +copystrings (struct Ebl_WStrent *nodep, wchar_t **freep, size_t *offsetp) +{ + struct Ebl_WStrent *subs; + + if (nodep->left != NULL) + copystrings (nodep->left, freep, offsetp); + + /* Process the current node. */ + nodep->offset = *offsetp; + *freep = wmempcpy (*freep, nodep->string, nodep->len); + *offsetp += nodep->len * sizeof (wchar_t); + + for (subs = nodep->next; subs != NULL; subs = subs->next) + { + assert (subs->len < nodep->len); + subs->offset = nodep->offset + nodep->len - subs->len; + assert (subs->offset != 0 || subs->string[0] == '\0'); + } + + if (nodep->right != NULL) + copystrings (nodep->right, freep, offsetp); +} + + +void +ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data) +{ + size_t copylen; + wchar_t *endp; + size_t nulllen = st->nullstr ? 1 : 0; + + /* Fill in the information. */ + data->d_buf = malloc ((st->total + nulllen) * sizeof (wchar_t)); + if (data->d_buf == NULL) + abort (); + + /* The first byte must always be zero if we created the table with a + null string. */ + if (st->nullstr) + *((wchar_t *) data->d_buf) = L'\0'; + + data->d_type = ELF_T_BYTE; + data->d_size = st->total + nulllen; + data->d_off = 0; + data->d_align = 1; + data->d_version = EV_CURRENT; + + /* Now run through the tree and add all the string while also updating + the offset members of the elfstrent records. */ + endp = (wchar_t *) data->d_buf + nulllen; + copylen = sizeof (wchar_t) * nulllen; + copystrings (st->root, &endp, ©len); + assert (copylen == (st->total + nulllen) * sizeof (wchar_t)); +} + + +size_t +ebl_wstrtaboffset (struct Ebl_WStrent *se) +{ + return se->offset; +} diff --git a/libebl/i386_corenote.c b/libebl/i386_corenote.c new file mode 100644 index 00000000..3a123e92 --- /dev/null +++ b/libebl/i386_corenote.c @@ -0,0 +1,162 @@ +/* i386 specific core note handling. + 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 + 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_i386.h> + + +/* 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 + { + 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. */ + 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. */ + }; + + +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. */ + 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. */ + }; + + +bool +i386_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" 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, 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], + stat->pr_reg[14], stat->pr_reg[11], stat->pr_reg[13] & 0xffff, + stat->pr_reg[7] & 0xffff, stat->pr_reg[8] & 0xffff, + stat->pr_reg[9] & 0xffff, stat->pr_reg[10] & 0xffff, + stat->pr_reg[16]); + + /* 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" 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, + 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/libebl/i386_destr.c b/libebl/i386_destr.c new file mode 100644 index 00000000..50c0fd48 --- /dev/null +++ b/libebl/i386_destr.c @@ -0,0 +1,27 @@ +/* Destructor for i386 specific backend library. + 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 + 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_i386.h> + + +void +i386_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/i386_init.c b/libebl/i386_init.c new file mode 100644 index 00000000..264f3ef7 --- /dev/null +++ b/libebl/i386_init.c @@ -0,0 +1,47 @@ +/* Initialization of i386 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_i386.h> + + +const char * +i386_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 NULL; + + /* We handle it. */ + eh->name = "Intel 80386"; + eh->reloc_type_name = i386_reloc_type_name; + eh->reloc_type_check = i386_reloc_type_check; + eh->reloc_valid_use = i386_reloc_valid_use; + 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 MODVERSION; +} diff --git a/libebl/i386_symbol.c b/libebl/i386_symbol.c new file mode 100644 index 00000000..e9eded23 --- /dev/null +++ b/libebl/i386_symbol.c @@ -0,0 +1,163 @@ +/* i386 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 <assert.h> +#include <elf.h> +#include <stddef.h> +#include <string.h> + +#include <libebl_i386.h> + + +/* Return of the backend. */ +const char * +i386_backend_name (void) +{ + return "i386"; +} + + +/* Relocation mapping table. */ +static struct +{ + const char *name; + enum { both = 0, rel = 1, exec = 2 } appear; +} reloc_map_table[] = + { + [R_386_NONE] = { "R_386_NONE", both }, + [R_386_32] = { "R_386_32", both }, + [R_386_PC32] = { "R_386_PC32", rel }, + [R_386_GOT32] = { "R_386_GOT32", rel }, + [R_386_PLT32] = { "R_386_PLT32", rel }, + [R_386_COPY] = { "R_386_COPY", exec }, + [R_386_GLOB_DAT] = { "R_386_GLOB_DAT", exec }, + [R_386_JMP_SLOT] = { "R_386_JMP_SLOT", exec }, + [R_386_RELATIVE] = { "R_386_RELATIVE", exec }, + [R_386_GOTOFF] = { "R_386_GOTOFF", rel }, + [R_386_GOTPC] = { "R_386_GOTPC", rel }, + [R_386_32PLT] = { "R_386_32PLT", rel }, + [R_386_TLS_TPOFF] = { "R_386_TLS_TPOFF", rel }, + [R_386_TLS_IE] = { "R_386_TLS_IE", rel }, + [R_386_TLS_GOTIE] = { "R_386_TLS_GOTIE", rel }, + [R_386_TLS_LE] = { "R_386_TLS_LE", rel }, + [R_386_TLS_GD] = { "R_386_TLS_GD", rel }, + [R_386_TLS_LDM] = { "R_386_TLS_LDM", rel }, + [R_386_16] = { "R_386_16", rel }, + [R_386_PC16] = { "R_386_PC16", rel }, + [R_386_8] = { "R_386_8", rel }, + [R_386_PC8] = { "R_386_PC8", rel }, + [R_386_TLS_GD_32] = { "R_386_TLS_GD_32", rel }, + [R_386_TLS_GD_PUSH] = { "R_386_TLS_GD_PUSH", rel }, + [R_386_TLS_GD_CALL] = { "R_386_TLS_GD_CALL", rel }, + [R_386_TLS_GD_POP] = { "R_386_TLS_GD_POP", rel }, + [R_386_TLS_LDM_32] = { "R_386_TLS_LDM_32", rel }, + [R_386_TLS_LDM_PUSH] = { "R_386_TLS_LDM_PUSH", rel }, + [R_386_TLS_LDM_CALL] = { "R_386_TLS_LDM_CALL", rel }, + [R_386_TLS_LDM_POP] = { "R_386_TLS_LDM_POP", rel }, + [R_386_TLS_LDO_32] = { "R_386_TLS_LDO_32", rel }, + [R_386_TLS_IE_32] = { "R_386_TLS_IE_32", rel }, + [R_386_TLS_LE_32] = { "R_386_TLS_LE_32", rel }, + [R_386_TLS_DTPMOD32] = { "R_386_TLS_DTPMOD32", rel }, + [R_386_TLS_DTPOFF32] = { "R_386_TLS_DTPOFF32", rel }, + [R_386_TLS_TPOFF32] = { "R_386_TLS_TPOFF32", rel } + }; + + +/* Determine relocation type string for x86. */ +const char * +i386_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type < 0 || type >= R_386_NUM) + return NULL; + + return reloc_map_table[type].name; +} + + +/* Check for correct relocation type. */ +bool +i386_reloc_type_check (int type) +{ + return (type >= R_386_NONE && type < R_386_NUM + && reloc_map_table[type].name != NULL) ? true : false; +} + + +/* Check for correct relocation type use. */ +bool +i386_reloc_valid_use (Elf *elf, int type) +{ + if (type < R_386_NONE || type >= R_386_NUM + || reloc_map_table[type].name == NULL) + return false; + + Elf32_Ehdr *ehdr = elf32_getehdr (elf); + assert (ehdr != NULL); + + if (reloc_map_table[type].appear == rel) + return ehdr->e_type == ET_REL; + + if (reloc_map_table[type].appear == exec) + return ehdr->e_type != ET_REL; + + assert (reloc_map_table[type].appear == both); + return true; +} + + +/* Return true if the symbol type is that referencing the GOT. */ +bool +i386_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type) +{ + return type == R_386_GOTPC; +} + +/* Check for the simple reloc types. */ +Elf_Type +i386_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type) +{ + switch (type) + { + case R_386_32: + return ELF_T_SWORD; + case R_386_16: + return ELF_T_HALF; + case R_386_8: + return ELF_T_BYTE; + default: + 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/libebl/ia64_destr.c b/libebl/ia64_destr.c new file mode 100644 index 00000000..cb105f64 --- /dev/null +++ b/libebl/ia64_destr.c @@ -0,0 +1,27 @@ +/* Destructor for IA-64 specific backend library. + 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 + 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_ia64.h> + + +void +ia64_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/ia64_init.c b/libebl/ia64_init.c new file mode 100644 index 00000000..3cafe5de --- /dev/null +++ b/libebl/ia64_init.c @@ -0,0 +1,43 @@ +/* Initialization of IA-64 specific backend library. + Copyright (C) 2002, 2003, 2005 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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_ia64.h> + + +const char * +ia64_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 NULL; + + /* We handle it. */ + eh->name = "Intel IA-64"; + eh->reloc_type_name = ia64_reloc_type_name; + 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->destr = ia64_destr; + + return MODVERSION; +} diff --git a/libebl/ia64_symbol.c b/libebl/ia64_symbol.c new file mode 100644 index 00000000..77ced76d --- /dev/null +++ b/libebl/ia64_symbol.c @@ -0,0 +1,187 @@ +/* IA-64 specific symbolic name handling. + Copyright (C) 2002, 2003, 2005 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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_ia64.h> + + +/* Return of the backend. */ +const char * +ia64_backend_name (void) +{ + return "ia64"; +} + + +/* Relocation mapping table. */ +static const char *reloc_map_table[] = + { + [R_IA64_NONE] = "R_IA64_NONE", + [R_IA64_IMM14] = "R_IA64_IMM14", + [R_IA64_IMM22] = "R_IA64_IMM22", + [R_IA64_IMM64] = "R_IA64_IMM64", + [R_IA64_DIR32MSB] = "R_IA64_DIR32MSB", + [R_IA64_DIR32LSB] = "R_IA64_DIR32LSB", + [R_IA64_DIR64MSB] = "R_IA64_DIR64MSB", + [R_IA64_DIR64LSB] = "R_IA64_DIR64LSB", + [R_IA64_GPREL22] = "R_IA64_GPREL22", + [R_IA64_GPREL64I] = "R_IA64_GPREL64I", + [R_IA64_GPREL32MSB] = "R_IA64_GPREL32MSB", + [R_IA64_GPREL32LSB] = "R_IA64_GPREL32LSB", + [R_IA64_GPREL64MSB] = "R_IA64_GPREL64MSB", + [R_IA64_GPREL64LSB] = "R_IA64_GPREL64LSB", + [R_IA64_LTOFF22] = "R_IA64_LTOFF22", + [R_IA64_LTOFF64I] = "R_IA64_LTOFF64I", + [R_IA64_PLTOFF22] = "R_IA64_PLTOFF22", + [R_IA64_PLTOFF64I] = "R_IA64_PLTOFF64I", + [R_IA64_PLTOFF64MSB] = "R_IA64_PLTOFF64MSB", + [R_IA64_PLTOFF64LSB] = "R_IA64_PLTOFF64LSB", + [R_IA64_FPTR64I] = "R_IA64_FPTR64I", + [R_IA64_FPTR32MSB] = "R_IA64_FPTR32MSB", + [R_IA64_FPTR32LSB] = "R_IA64_FPTR32LSB", + [R_IA64_FPTR64MSB] = "R_IA64_FPTR64MSB", + [R_IA64_FPTR64LSB] = "R_IA64_FPTR64LSB", + [R_IA64_PCREL60B] = "R_IA64_PCREL60B", + [R_IA64_PCREL21B] = "R_IA64_PCREL21B", + [R_IA64_PCREL21M] = "R_IA64_PCREL21M", + [R_IA64_PCREL21F] = "R_IA64_PCREL21F", + [R_IA64_PCREL32MSB] = "R_IA64_PCREL32MSB", + [R_IA64_PCREL32LSB] = "R_IA64_PCREL32LSB", + [R_IA64_PCREL64MSB] = "R_IA64_PCREL64MSB", + [R_IA64_PCREL64LSB] = "R_IA64_PCREL64LSB", + [R_IA64_LTOFF_FPTR22] = "R_IA64_LTOFF_FPTR22", + [R_IA64_LTOFF_FPTR64I] = "R_IA64_LTOFF_FPTR64I", + [R_IA64_LTOFF_FPTR32MSB] = "R_IA64_LTOFF_FPTR32MSB", + [R_IA64_LTOFF_FPTR32LSB] = "R_IA64_LTOFF_FPTR32LSB", + [R_IA64_LTOFF_FPTR64MSB] = "R_IA64_LTOFF_FPTR64MSB", + [R_IA64_LTOFF_FPTR64LSB] = "R_IA64_LTOFF_FPTR64LSB", + [R_IA64_SEGREL32MSB] = "R_IA64_SEGREL32MSB", + [R_IA64_SEGREL32LSB] = "R_IA64_SEGREL32LSB", + [R_IA64_SEGREL64MSB] = "R_IA64_SEGREL64MSB", + [R_IA64_SEGREL64LSB] = "R_IA64_SEGREL64LSB", + [R_IA64_SECREL32MSB] = "R_IA64_SECREL32MSB", + [R_IA64_SECREL32LSB] = "R_IA64_SECREL32LSB", + [R_IA64_SECREL64MSB] = "R_IA64_SECREL64MSB", + [R_IA64_SECREL64LSB] = "R_IA64_SECREL64LSB", + [R_IA64_REL32MSB] = "R_IA64_REL32MSB", + [R_IA64_REL32LSB] = "R_IA64_REL32LSB", + [R_IA64_REL64MSB] = "R_IA64_REL64MSB", + [R_IA64_REL64LSB] = "R_IA64_REL64LSB", + [R_IA64_LTV32MSB] = "R_IA64_LTV32MSB", + [R_IA64_LTV32LSB] = "R_IA64_LTV32LSB", + [R_IA64_LTV64MSB] = "R_IA64_LTV64MSB", + [R_IA64_LTV64LSB] = "R_IA64_LTV64LSB", + [R_IA64_PCREL21BI] = "R_IA64_PCREL21BI", + [R_IA64_PCREL22] = "R_IA64_PCREL22", + [R_IA64_PCREL64I] = "R_IA64_PCREL64I", + [R_IA64_IPLTMSB] = "R_IA64_IPLTMSB", + [R_IA64_IPLTLSB] = "R_IA64_IPLTLSB", + [R_IA64_COPY] = "R_IA64_COPY", + [R_IA64_SUB] = "R_IA64_SUB", + [R_IA64_LTOFF22X] = "R_IA64_LTOFF22X", + [R_IA64_LDXMOV] = "R_IA64_LDXMOV", + [R_IA64_TPREL14] = "R_IA64_TPREL14", + [R_IA64_TPREL22] = "R_IA64_TPREL22", + [R_IA64_TPREL64I] = "R_IA64_TPREL64I", + [R_IA64_TPREL64MSB] = "R_IA64_TPREL64MSB", + [R_IA64_TPREL64LSB] = "R_IA64_TPREL64LSB", + [R_IA64_LTOFF_TPREL22] = "R_IA64_LTOFF_TPREL22", + [R_IA64_DTPMOD64MSB] = "R_IA64_DTPMOD64MSB", + [R_IA64_DTPMOD64LSB] = "R_IA64_DTPMOD64LSB", + [R_IA64_LTOFF_DTPMOD22] = "R_IA64_LTOFF_DTPMOD22", + [R_IA64_DTPREL14] = "R_IA64_DTPREL14", + [R_IA64_DTPREL22] = "R_IA64_DTPREL22", + [R_IA64_DTPREL64I] = "R_IA64_DTPREL64I", + [R_IA64_DTPREL32MSB] = "R_IA64_DTPREL32MSB", + [R_IA64_DTPREL32LSB] = "R_IA64_DTPREL32LSB", + [R_IA64_DTPREL64MSB] = "R_IA64_DTPREL64MSB", + [R_IA64_DTPREL64LSB] = "R_IA64_DTPREL64LSB", + [R_IA64_LTOFF_DTPREL22] = "R_IA64_LTOFF_DTPREL22" + }; + + +/* Determine relocation type string for IA-64. */ +const char * +ia64_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type < 0 + || ((size_t) type + >= sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))) + return NULL; + + return reloc_map_table[type]; +} + + +/* Check for correct relocation type. */ +bool +ia64_reloc_type_check (int type) +{ + return (type >= R_IA64_NONE + && ((size_t) type + < sizeof (reloc_map_table) / sizeof (reloc_map_table[0])) + && reloc_map_table[type] != NULL) ? true : false; +} + + +const char * +ia64_segment_type_name (int segment, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (segment) + { + case PT_IA_64_ARCHEXT: + return "IA_64_ARCHEXT"; + case PT_IA_64_UNWIND: + return "IA_64_UNWIND"; + case PT_IA_64_HP_OPT_ANOT: + return "IA_64_HP_OPT_ANOT"; + case PT_IA_64_HP_HSL_ANOT: + return "IA_64_HP_HSL_ANOT"; + case PT_IA_64_HP_STACK: + return "IA_64_HP_STACK"; + default: + break; + } + return NULL; +} + + +const char * +ia64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_IA_64_PLT_RESERVE: + return "IA_64_PLT_RESERVE"; + default: + break; + } + return NULL; +} + +/* Check whether given relocation is a copy relocation. */ +bool +ia64_copy_reloc_p (int reloc) +{ + return reloc == R_IA64_COPY; +} diff --git a/libebl/libebl.h b/libebl/libebl.h new file mode 100644 index 00000000..aff9ca5e --- /dev/null +++ b/libebl/libebl.h @@ -0,0 +1,208 @@ +/* Interface for libebl. + 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 + 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_H +#define _LIBEBL_H 1 + +#include <gelf.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <elf-knowledge.h> + + +/* Opaque type for the handle. */ +typedef struct ebl Ebl; + + +/* Get backend handle for object associated with ELF handle. */ +extern Ebl *ebl_openbackend (Elf *elf); +/* Similar but without underlying ELF file. */ +extern Ebl *ebl_openbackend_machine (GElf_Half machine); +/* Similar but with emulation name given. */ +extern Ebl *ebl_openbackend_emulation (const char *emulation); + +/* Free resources allocated for backend handle. */ +extern void ebl_closebackend (Ebl *bh); + + +/* Function to call the callback functions including default ELF + handling. */ + +/* Return backend name. */ +extern const char *ebl_backend_name (Ebl *ebl); + +/* Return relocation type name. */ +extern const char *ebl_object_type_name (Ebl *ebl, int object, + char *buf, size_t len); + +/* Return relocation type name. */ +extern const char *ebl_reloc_type_name (Ebl *ebl, int reloc, + char *buf, size_t len); + +/* Check relocation type. */ +extern bool ebl_reloc_type_check (Ebl *ebl, int reloc); + +/* Check relocation type use. */ +extern bool ebl_reloc_valid_use (Ebl *ebl, int reloc); + +/* Check if relocation type is for simple absolute relocations. + Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM. */ +extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc); + +/* Return true if the symbol type is that referencing the GOT. E.g., + R_386_GOTPC. */ +extern bool ebl_gotpc_reloc_check (Ebl *ebl, int reloc); + +/* Return segment type name. */ +extern const char *ebl_segment_type_name (Ebl *ebl, int segment, + char *buf, size_t len); + +/* Return section type name. */ +extern const char *ebl_section_type_name (Ebl *ebl, int section, + char *buf, size_t len); + +/* Return section name. */ +extern const char *ebl_section_name (Ebl *ebl, int section, int xsection, + char *buf, size_t len, + const char *scnnames[], size_t shnum); + +/* Return machine flag names. */ +extern const char *ebl_machine_flag_name (Ebl *ebl, GElf_Word flags, + char *buf, size_t len); + +/* Check whether machine flag is valid. */ +extern bool ebl_machine_flag_check (Ebl *ebl, GElf_Word flags); + +/* Return symbol type name. */ +extern const char *ebl_symbol_type_name (Ebl *ebl, int symbol, + char *buf, size_t len); + +/* Return symbol binding name. */ +extern const char *ebl_symbol_binding_name (Ebl *ebl, int binding, + char *buf, size_t len); + +/* Return dynamic tag name. */ +extern const char *ebl_dynamic_tag_name (Ebl *ebl, int64_t tag, + char *buf, size_t len); + +/* Check dynamic tag. */ +extern bool ebl_dynamic_tag_check (Ebl *ebl, int64_t tag); + +/* Return combined section header flags value. */ +extern GElf_Word ebl_sh_flags_combine (Ebl *ebl, GElf_Word flags1, + GElf_Word flags2); + +/* Return symbolic representation of OS ABI. */ +extern const char *ebl_osabi_name (Ebl *ebl, int osabi, char *buf, size_t len); + + +/* Return name of the note section type for a core file. */ +extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf, + size_t len); + +/* Return name of the note section type for an object file. */ +extern const char *ebl_object_note_type_name (Ebl *ebl, uint32_t type, + char *buf, size_t len); + +/* Print information about core note if available. */ +extern void ebl_core_note (Ebl *ebl, const char *name, uint32_t type, + uint32_t descsz, const char *desc); + +/* Print information about object note if available. */ +extern void ebl_object_note (Ebl *ebl, 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 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); + + +/* ELF string table handling. */ +struct Ebl_Strtab; +struct Ebl_Strent; + +/* Create new ELF string table object in memory. */ +extern struct Ebl_Strtab *ebl_strtabinit (bool nullstr); + +/* Free resources allocated for ELF string table ST. */ +extern void ebl_strtabfree (struct Ebl_Strtab *st); + +/* Add string STR (length LEN is != 0) to ELF string table ST. */ +extern struct Ebl_Strent *ebl_strtabadd (struct Ebl_Strtab *st, + const char *str, size_t len); + +/* Finalize string table ST and store size and memory location information + in DATA. */ +extern void ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data); + +/* Get offset in string table for string associated with SE. */ +extern size_t ebl_strtaboffset (struct Ebl_Strent *se); + +/* Return the string associated with SE. */ +extern const char *ebl_string (struct Ebl_Strent *se); + + +/* ELF wide char string table handling. */ +struct Ebl_WStrtab; +struct Ebl_WStrent; + +/* Create new ELF wide char string table object in memory. */ +extern struct Ebl_WStrtab *ebl_wstrtabinit (bool nullstr); + +/* Free resources allocated for ELF wide char string table ST. */ +extern void ebl_wstrtabfree (struct Ebl_WStrtab *st); + +/* Add string STR (length LEN is != 0) to ELF string table ST. */ +extern struct Ebl_WStrent *ebl_wstrtabadd (struct Ebl_WStrtab *st, + const wchar_t *str, size_t len); + +/* Finalize string table ST and store size and memory location information + in DATA. */ +extern void ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data); + +/* Get offset in wide char string table for string associated with SE. */ +extern size_t ebl_wstrtaboffset (struct Ebl_WStrent *se); + + +/* Generic string table handling. */ +struct Ebl_GStrtab; +struct Ebl_GStrent; + +/* Create new string table object in memory. */ +extern struct Ebl_GStrtab *ebl_gstrtabinit (unsigned int width, bool nullstr); + +/* Free resources allocated for string table ST. */ +extern void ebl_gstrtabfree (struct Ebl_GStrtab *st); + +/* Add string STR (length LEN is != 0) to string table ST. */ +extern struct Ebl_GStrent *ebl_gstrtabadd (struct Ebl_GStrtab *st, + const char *str, size_t len); + +/* Finalize string table ST and store size and memory location information + in DATA. */ +extern void ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data); + +/* Get offset in wide char string table for string associated with SE. */ +extern size_t ebl_gstrtaboffset (struct Ebl_GStrent *se); + +#endif /* libebl.h */ diff --git a/libebl/libeblP.h b/libebl/libeblP.h new file mode 100644 index 00000000..21bb8fff --- /dev/null +++ b/libebl/libeblP.h @@ -0,0 +1,118 @@ +/* Internal definitions for interface for libebl. + 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 + 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 _LIBEBLP_H +#define _LIBEBLP_H 1 + +#include <gelf.h> +#include <libebl.h> +#include <libintl.h> + + +/* Backend handle. */ +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 *); + + /* Check whether given relocation is a copy relocation. */ + bool (*copy_reloc_p) (int); + + /* Destructor for ELF backend handle. */ + void (*destr) (struct ebl *); + + /* Internal data. */ + void *dlhandle; +}; + + +/* Type of the initialization functions in the backend modules. */ +typedef const char *(*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *, size_t); + + +/* gettext helper macros. */ +#define _(Str) dgettext ("elfutils", Str) + +#endif /* libeblP.h */ diff --git a/libebl/libebl_alpha.h b/libebl/libebl_alpha.h new file mode 100644 index 00000000..7990d995 --- /dev/null +++ b/libebl/libebl_alpha.h @@ -0,0 +1,37 @@ +/* Interface for libebl_alpha module. + 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 + 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_ALPHA_H +#define _LIBEBL_ALPHA_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *alpha_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void alpha_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +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); + +/* Check whether given relocation is a copy relocation. */ +extern bool alpha_copy_reloc_p (int reloc); + +#endif /* libebl_alpha.h */ diff --git a/libebl/libebl_alpha.map b/libebl/libebl_alpha.map new file mode 100644 index 00000000..aa66ad75 --- /dev/null +++ b/libebl/libebl_alpha.map @@ -0,0 +1,11 @@ +ELFUTILS_1.0 { + global: + alpha_backend_name; + alpha_destr; + alpha_init; + alpha_reloc_type_check; + alpha_reloc_type_name; + + local: + *; +}; diff --git a/libebl/libebl_arm.h b/libebl/libebl_arm.h new file mode 100644 index 00000000..18bb99c4 --- /dev/null +++ b/libebl/libebl_arm.h @@ -0,0 +1,37 @@ +/* Interface for libebl_arm module. + 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 + 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_ARM_H +#define _LIBEBL_ARM_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *arm_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void arm_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +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/libebl/libebl_arm.map b/libebl/libebl_arm.map new file mode 100644 index 00000000..d389526c --- /dev/null +++ b/libebl/libebl_arm.map @@ -0,0 +1,11 @@ +ELFUTILS_1.0 { + global: + arm_backend_name; + arm_destr; + arm_init; + arm_reloc_type_check; + arm_reloc_type_name; + + local: + *; +}; diff --git a/libebl/libebl_i386.h b/libebl/libebl_i386.h new file mode 100644 index 00000000..ef2b3199 --- /dev/null +++ b/libebl/libebl_i386.h @@ -0,0 +1,54 @@ +/* Interface for libebl_i386 module. + Copyright (C) 2000, 2001, 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 + 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_I386_H +#define _LIBEBL_I386_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *i386_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void i386_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +extern const char *i386_reloc_type_name (int type, char *buf, size_t len); + +/* Check relocation type. */ +extern bool i386_reloc_type_check (int type); + +/* Check relocation type use. */ +extern bool i386_reloc_valid_use (Elf *elf, int type); + +/* Check for the simple reloc types. */ +extern Elf_Type i386_reloc_simple_type (Elf *elf, int type); + +/* Check relocation type use. */ +extern bool i386_gotpc_reloc_check (Elf *elf, int type); + +/* Code note handling. */ +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/libebl/libebl_i386.map b/libebl/libebl_i386.map new file mode 100644 index 00000000..d0c910c7 --- /dev/null +++ b/libebl/libebl_i386.map @@ -0,0 +1,14 @@ +ELFUTILS_1.0 { + global: + i386_backend_name; + i386_core_note; + i386_destr; + i386_init; + i386_reloc_type_check; + i386_reloc_type_name; + i386_reloc_valid_use; + i386_reloc_simple_type; + + local: + *; +}; diff --git a/libebl/libebl_ia64.h b/libebl/libebl_ia64.h new file mode 100644 index 00000000..8dea6500 --- /dev/null +++ b/libebl/libebl_ia64.h @@ -0,0 +1,43 @@ +/* Interface for libebl_ia64 module. + 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 + 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_IA64_H +#define _LIBEBL_IA64_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *ia64_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void ia64_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +extern const char *ia64_reloc_type_name (int type, char *buf, size_t len); + +/* Check relocation type. */ +extern bool ia64_reloc_type_check (int type); + +/* Name of segment type. */ +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); + +#endif /* libebl_ia64.h */ diff --git a/libebl/libebl_ia64.map b/libebl/libebl_ia64.map new file mode 100644 index 00000000..f67042c6 --- /dev/null +++ b/libebl/libebl_ia64.map @@ -0,0 +1,11 @@ +ELFUTILS_1.0 { + global: + ia64_backend_name; + ia64_destr; + ia64_init; + ia64_reloc_type_check; + ia64_reloc_type_name; + + local: + *; +}; diff --git a/libebl/libebl_ppc.h b/libebl/libebl_ppc.h new file mode 100644 index 00000000..1e646d4f --- /dev/null +++ b/libebl/libebl_ppc.h @@ -0,0 +1,47 @@ +/* Interface for libebl_PPC module. + Copyright (C) 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 + 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_PPC_H +#define _LIBEBL_PPC_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *ppc_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void ppc_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +extern const char *ppc_reloc_type_name (int type, char *buf, size_t len); + +/* Check relocation type. */ +extern bool ppc_reloc_type_check (int type); + +/* Check relocation type use. */ +extern bool ppc_reloc_valid_use (Elf *elf, int type); + +/* Check for the simple reloc types. */ +extern Elf_Type ppc_reloc_simple_type (Elf *elf, int type); + +/* Code note handling. */ +extern bool ppc_core_note (const char *name, uint32_t type, uint32_t descsz, + const char *desc); + +/* Check whether given relocation is a copy relocation. */ +extern bool ppc_copy_reloc_p (int reloc); + +#endif /* libebl_ppc.h */ diff --git a/libebl/libebl_ppc.map b/libebl/libebl_ppc.map new file mode 100644 index 00000000..3d49c0b3 --- /dev/null +++ b/libebl/libebl_ppc.map @@ -0,0 +1,12 @@ +ELFUTILS_1.0 { + global: + ppc_backend_name; + ppc_destr; + ppc_init; + ppc_reloc_type_check; + ppc_reloc_type_name; + ppc_reloc_simple_type; + + local: + *; +}; diff --git a/libebl/libebl_ppc64.h b/libebl/libebl_ppc64.h new file mode 100644 index 00000000..e737c56a --- /dev/null +++ b/libebl/libebl_ppc64.h @@ -0,0 +1,50 @@ +/* Interface for libebl_PPC64 module. + Copyright (C) 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 + 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_PPC64_H +#define _LIBEBL_PPC64_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *ppc64_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void ppc64_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +extern const char *ppc64_reloc_type_name (int type, char *buf, size_t len); + +/* Check relocation type. */ +extern bool ppc64_reloc_type_check (int type); + +/* Check relocation type use. */ +extern bool ppc64_reloc_valid_use (Elf *elf, int type); + +/* Check for the simple reloc types. */ +extern Elf_Type ppc64_reloc_simple_type (Elf *elf, int type); + +/* Code note handling. */ +extern bool ppc64_core_note (const char *name, uint32_t type, uint32_t descsz, + const char *desc); + +/* Name of dynamic tag. */ +extern const char *ppc64_dynamic_tag_name (int64_t tag, char *buf, size_t len); + +/* Check whether given relocation is a copy relocation. */ +extern bool ppc64_copy_reloc_p (int reloc); + +#endif /* libebl_ppc.h */ diff --git a/libebl/libebl_ppc64.map b/libebl/libebl_ppc64.map new file mode 100644 index 00000000..260805d4 --- /dev/null +++ b/libebl/libebl_ppc64.map @@ -0,0 +1,12 @@ +ELFUTILS_1.0 { + global: + ppc64_backend_name; + ppc64_destr; + ppc64_init; + ppc64_reloc_type_check; + ppc64_reloc_type_name; + ppc64_reloc_simple_type; + + local: + *; +}; diff --git a/libebl/libebl_sh.h b/libebl/libebl_sh.h new file mode 100644 index 00000000..32b029a7 --- /dev/null +++ b/libebl/libebl_sh.h @@ -0,0 +1,34 @@ +/* Interface for libebl_sh module. + 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 + 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_SH_H +#define _LIBEBL_SH_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *sh_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +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/libebl/libebl_sh.map b/libebl/libebl_sh.map new file mode 100644 index 00000000..252720a9 --- /dev/null +++ b/libebl/libebl_sh.map @@ -0,0 +1,10 @@ +ELFUTILS_1.0 { + global: + sh_backend_name; + sh_destr; + sh_init; + sh_reloc_type_name; + + local: + *; +}; diff --git a/libebl/libebl_sparc.h b/libebl/libebl_sparc.h new file mode 100644 index 00000000..077db170 --- /dev/null +++ b/libebl/libebl_sparc.h @@ -0,0 +1,41 @@ +/* Interface for libebl_sparc module. + 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 + 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_SPARC_H +#define _LIBEBL_SPARC_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *sparc_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void sparc_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +extern const char *sparc_reloc_type_name (int type, char *buf, size_t len); + +/* Check relocation type. */ +extern bool sparc_reloc_type_check (int type); + +/* Code note handling. */ +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/libebl/libebl_sparc.map b/libebl/libebl_sparc.map new file mode 100644 index 00000000..7ca60383 --- /dev/null +++ b/libebl/libebl_sparc.map @@ -0,0 +1,11 @@ +ELFUTILS_1.0 { + global: + sparc_backend_name; + sparc_destr; + sparc_init; + sparc_reloc_type_check; + sparc_reloc_type_name; + + local: + *; +}; diff --git a/libebl/libebl_x86_64.h b/libebl/libebl_x86_64.h new file mode 100644 index 00000000..025edb63 --- /dev/null +++ b/libebl/libebl_x86_64.h @@ -0,0 +1,47 @@ +/* Interface for libebl_x86_64 module. + 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 + 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_X86_64_H +#define _LIBEBL_X86_64_H 1 + +#include <libeblP.h> + + +/* Constructor. */ +extern const char *x86_64_init (Elf *elf, GElf_Half machine, Ebl *eh, + size_t ehlen); + +/* Destructor. */ +extern void x86_64_destr (Ebl *bh); + + +/* Function to get relocation type name. */ +extern const char *x86_64_reloc_type_name (int type, char *buf, size_t len); + +/* Check relocation type. */ +extern bool x86_64_reloc_type_check (int type); + +/* Check relocation type use. */ +extern bool x86_64_reloc_valid_use (Elf *elf, int type); + +/* Check for the simple reloc types. */ +extern Elf_Type x86_64_reloc_simple_type (Elf *elf, int type); + +/* Code note handling. */ +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/libebl/libebl_x86_64.map b/libebl/libebl_x86_64.map new file mode 100644 index 00000000..e6d1c7bd --- /dev/null +++ b/libebl/libebl_x86_64.map @@ -0,0 +1,13 @@ +ELFUTILS_1.0 { + global: + x86_64_backend_name; + x86_64_core_note; + x86_64_destr; + x86_64_init; + x86_64_reloc_type_check; + x86_64_reloc_type_name; + x86_64_reloc_simple_type; + + local: + *; +}; diff --git a/libebl/ppc64_destr.c b/libebl/ppc64_destr.c new file mode 100644 index 00000000..8da6a8fd --- /dev/null +++ b/libebl/ppc64_destr.c @@ -0,0 +1,27 @@ +/* Destructor for PPC64 specific backend library. + 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 + 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_ppc64.h> + + +void +ppc64_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/ppc64_init.c b/libebl/ppc64_init.c new file mode 100644 index 00000000..8231a32d --- /dev/null +++ b/libebl/ppc64_init.c @@ -0,0 +1,44 @@ +/* Initialization of PPC64 specific backend library. + 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 + 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_ppc64.h> + + +const char * +ppc64_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 NULL; + + /* We handle it. */ + eh->name = "PowerPC 64-bit"; + eh->reloc_type_name = ppc64_reloc_type_name; + eh->reloc_type_check = ppc64_reloc_type_check; + 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->copy_reloc_p = ppc64_copy_reloc_p; + eh->destr = ppc64_destr; + + return MODVERSION; +} diff --git a/libebl/ppc64_symbol.c b/libebl/ppc64_symbol.c new file mode 100644 index 00000000..f844816b --- /dev/null +++ b/libebl/ppc64_symbol.c @@ -0,0 +1,235 @@ +/* PPC64 specific symbolic name handling. + 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 + 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 <elf.h> +#include <stddef.h> + +#include <libebl_ppc64.h> + + +/* Return of the backend. */ +const char * +ppc64_backend_name (void) +{ + return "ppc64"; +} + + +/* Relocation mapping table. */ +static struct +{ + const char *name; + enum { both = 0, rel = 1, exec = 2 } appear; +} reloc_map_table[] = + { + // XXX Check all the appear values. + [R_PPC64_NONE] = { "R_PPC64_NONE", both }, + [R_PPC64_ADDR32] = { "R_PPC64_ADDR32", both }, + [R_PPC64_ADDR24] = { "R_PPC64_ADDR24", both }, + [R_PPC64_ADDR16] = { "R_PPC64_ADDR16", both }, + [R_PPC64_ADDR16_LO] = { "R_PPC64_ADDR16_LO", both }, + [R_PPC64_ADDR16_HI] = { "R_PPC64_ADDR16_HI", both }, + [R_PPC64_ADDR16_HA] = { "R_PPC64_ADDR16_HA", both }, + [R_PPC64_ADDR14] = { "R_PPC64_ADDR14", both }, + [R_PPC64_ADDR14_BRTAKEN] = { "R_PPC64_ADDR14_BRTAKEN", exec }, + [R_PPC64_ADDR14_BRNTAKEN] = { "R_PPC64_ADDR14_BRNTAKEN", exec }, + [R_PPC64_REL24] = { "R_PPC64_REL24", both }, + [R_PPC64_REL14] = { "R_PPC64_REL14", both }, + [R_PPC64_REL14_BRTAKEN] = { "R_PPC64_REL14_BRTAKEN", exec }, + [R_PPC64_REL14_BRNTAKEN] = { "R_PPC64_REL14_BRNTAKEN", exec }, + [R_PPC64_GOT16] = { "R_PPC64_GOT16", rel }, + [R_PPC64_GOT16_LO] = { "R_PPC64_GOT16_LO", rel }, + [R_PPC64_GOT16_HI] = { "R_PPC64_GOT16_HI", rel }, + [R_PPC64_GOT16_HA] = { "R_PPC64_GOT16_HA", rel }, + [R_PPC64_COPY] = { "R_PPC64_COPY", exec }, + [R_PPC64_GLOB_DAT] = { "R_PPC64_GLOB_DAT", exec }, + [R_PPC64_JMP_SLOT] = { "R_PPC64_JMP_SLOT", exec }, + [R_PPC64_RELATIVE] = { "R_PPC64_RELATIVE", exec }, + [R_PPC64_UADDR32] = { "R_PPC64_UADDR32", exec }, + [R_PPC64_UADDR16] = { "R_PPC64_UADDR16", exec }, + [R_PPC64_REL32] = { "R_PPC64_REL32", exec }, + [R_PPC64_PLT32] = { "R_PPC64_PLT32", exec }, + [R_PPC64_PLTREL32] = { "R_PPC64_PLTREL32", both }, + [R_PPC64_PLT16_LO] = { "R_PPC64_PLT16_LO", both }, + [R_PPC64_PLT16_HI] = { "R_PPC64_PLT16_HI", both }, + [R_PPC64_PLT16_HA] = { "R_PPC64_PLT16_HA", both }, + [R_PPC64_SECTOFF] = { "R_PPC64_SECTOFF", both }, + [R_PPC64_SECTOFF_LO] = { "R_PPC64_SECTOFF_LO", both }, + [R_PPC64_SECTOFF_HI] = { "R_PPC64_SECTOFF_HI", both }, + [R_PPC64_SECTOFF_HA] = { "R_PPC64_SECTOFF_HA", both }, + [R_PPC64_ADDR30] = { "R_PPC64_ADDR30", both }, + [R_PPC64_ADDR64] = { "R_PPC64_ADDR64", both }, + [R_PPC64_ADDR16_HIGHER] = { "R_PPC64_ADDR16_HIGHER", both }, + [R_PPC64_ADDR16_HIGHERA] = { "R_PPC64_ADDR16_HIGHERA", both }, + [R_PPC64_ADDR16_HIGHEST] = { "R_PPC64_ADDR16_HIGHEST", both }, + [R_PPC64_ADDR16_HIGHESTA] = { "R_PPC64_ADDR16_HIGHESTA", both }, + [R_PPC64_UADDR64] = { "R_PPC64_UADDR64", both }, + [R_PPC64_REL64] = { "R_PPC64_REL64", both }, + [R_PPC64_PLT64] = { "R_PPC64_PLT64", both }, + [R_PPC64_PLTREL64] = { "R_PPC64_PLTREL64", both }, + [R_PPC64_TOC16] = { "R_PPC64_TOC16", both }, + [R_PPC64_TOC16_LO] = { "R_PPC64_TOC16_LO", both }, + [R_PPC64_TOC16_HI] = { "R_PPC64_TOC16_HI", both }, + [R_PPC64_TOC16_HA] = { "R_PPC64_TOC16_HA", both }, + [R_PPC64_TOC] = { "R_PPC64_TOC", both }, + [R_PPC64_PLTGOT16] = { "R_PPC64_PLTGOT16", both }, + [R_PPC64_PLTGOT16_LO] = { "R_PPC64_PLTGOT16_LO", both }, + [R_PPC64_PLTGOT16_HI] = { "R_PPC64_PLTGOT16_HI", both }, + [R_PPC64_PLTGOT16_HA] = { "R_PPC64_PLTGOT16_HA", both }, + [R_PPC64_ADDR16_DS] = { "R_PPC64_ADDR16_DS", both }, + [R_PPC64_ADDR16_LO_DS] = { "R_PPC64_ADDR16_LO_DS", both }, + [R_PPC64_GOT16_DS] = { "R_PPC64_GOT16_DS", both }, + [R_PPC64_GOT16_LO_DS] = { "R_PPC64_GOT16_LO_DS", both }, + [R_PPC64_PLT16_LO_DS] = { "R_PPC64_PLT16_LO_DS", both }, + [R_PPC64_SECTOFF_DS] = { "R_PPC64_SECTOFF_DS", both }, + [R_PPC64_SECTOFF_LO_DS] = { "R_PPC64_SECTOFF_LO_DS", both }, + [R_PPC64_TOC16_DS] = { "R_PPC64_TOC16_DS", both }, + [R_PPC64_TOC16_LO_DS] = { "R_PPC64_TOC16_LO_DS", both }, + [R_PPC64_PLTGOT16_DS] = { "R_PPC64_PLTGOT16_DS", both }, + [R_PPC64_PLTGOT16_LO_DS] = { "R_PPC64_PLTGOT16_LO_DS", both }, + [R_PPC64_TLS] = { "R_PPC64_TLS", both }, + [R_PPC64_DTPMOD64] = { "R_PPC64_DTPMOD64", both }, + [R_PPC64_TPREL16] = { "R_PPC64_TPREL16", both }, + [R_PPC64_TPREL16_LO] = { "R_PPC64_TPREL16_LO", both }, + [R_PPC64_TPREL16_HI] = { "R_PPC64_TPREL16_HI", both }, + [R_PPC64_TPREL16_HA] = { "R_PPC64_TPREL16_HA", both }, + [R_PPC64_TPREL64] = { "R_PPC64_TPREL64", both }, + [R_PPC64_DTPREL16] = { "R_PPC64_DTPREL16", both }, + [R_PPC64_DTPREL16_LO] = { "R_PPC64_DTPREL16_LO", both }, + [R_PPC64_DTPREL16_HI] = { "R_PPC64_DTPREL16_HI", both }, + [R_PPC64_DTPREL16_HA] = { "R_PPC64_DTPREL16_HA", both }, + [R_PPC64_DTPREL64] = { "R_PPC64_DTPREL64", both }, + [R_PPC64_GOT_TLSGD16] = { "R_PPC64_GOT_TLSGD16", both }, + [R_PPC64_GOT_TLSGD16_LO] = { "R_PPC64_GOT_TLSGD16_LO", both }, + [R_PPC64_GOT_TLSGD16_HI] = { "R_PPC64_GOT_TLSGD16_HI", both }, + [R_PPC64_GOT_TLSGD16_HA] = { "R_PPC64_GOT_TLSGD16_HA", both }, + [R_PPC64_GOT_TLSLD16] = { "R_PPC64_GOT_TLSLD16", both }, + [R_PPC64_GOT_TLSLD16_LO] = { "R_PPC64_GOT_TLSLD16_LO", both }, + [R_PPC64_GOT_TLSLD16_HI] = { "R_PPC64_GOT_TLSLD16_HI", both }, + [R_PPC64_GOT_TLSLD16_HA] = { "R_PPC64_GOT_TLSLD16_HA", both }, + [R_PPC64_GOT_TPREL16_DS] = { "R_PPC64_GOT_TPREL16_DS", both }, + [R_PPC64_GOT_TPREL16_LO_DS] = { "R_PPC64_GOT_TPREL16_LO_DS", both }, + [R_PPC64_GOT_TPREL16_HI] = { "R_PPC64_GOT_TPREL16_HI", both }, + [R_PPC64_GOT_TPREL16_HA] = { "R_PPC64_GOT_TPREL16_HA", both }, + [R_PPC64_GOT_DTPREL16_DS] = { "R_PPC64_GOT_DTPREL16_DS", both }, + [R_PPC64_GOT_DTPREL16_LO_DS] = { "R_PPC64_GOT_DTPREL16_LO_DS", both }, + [R_PPC64_GOT_DTPREL16_HI] = { "R_PPC64_GOT_DTPREL16_HI", both }, + [R_PPC64_GOT_DTPREL16_HA] = { "R_PPC64_GOT_DTPREL16_HA", both }, + [R_PPC64_TPREL16_DS] = { "R_PPC64_TPREL16_DS", both }, + [R_PPC64_TPREL16_LO_DS] = { "R_PPC64_TPREL16_LO_DS", both }, + [R_PPC64_TPREL16_HIGHER] = { "R_PPC64_TPREL16_HIGHER", both }, + [R_PPC64_TPREL16_HIGHERA] = { "R_PPC64_TPREL16_HIGHERA", both }, + [R_PPC64_TPREL16_HIGHEST] = { "R_PPC64_TPREL16_HIGHEST", both }, + [R_PPC64_TPREL16_HIGHESTA] = { "R_PPC64_TPREL16_HIGHESTA", both }, + [R_PPC64_DTPREL16_DS] = { "R_PPC64_DTPREL16_DS", both }, + [R_PPC64_DTPREL16_LO_DS] = { "R_PPC64_DTPREL16_LO_DS", both }, + [R_PPC64_DTPREL16_HIGHER] = { "R_PPC64_DTPREL16_HIGHER", both }, + [R_PPC64_DTPREL16_HIGHERA] = { "R_PPC64_DTPREL16_HIGHERA", both }, + [R_PPC64_DTPREL16_HIGHEST] = { "R_PPC64_DTPREL16_HIGHEST", both }, + [R_PPC64_DTPREL16_HIGHESTA] = { "R_PPC64_DTPREL16_HIGHESTA", both } + }; + + +/* Determine relocation type string for PPC. */ +const char * +ppc64_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type < R_PPC64_NONE || type >= R_PPC64_NUM) + return NULL; + + return reloc_map_table[type].name; +} + + +/* Check for correct relocation type. */ +bool +ppc64_reloc_type_check (int type) +{ + return (type >= R_PPC64_NONE && type < R_PPC64_NUM + && reloc_map_table[type].name != NULL) ? true : false; +} + + +/* Check for correct relocation type use. */ +bool +ppc64_reloc_valid_use (Elf *elf, int type) +{ + if (type < R_PPC64_NONE || type >= R_PPC64_NUM + || reloc_map_table[type].name == NULL) + return false; + + Elf64_Ehdr *ehdr = elf64_getehdr (elf); + assert (ehdr != NULL); + + if (reloc_map_table[type].appear == rel) + return ehdr->e_type == ET_REL; + + if (reloc_map_table[type].appear == exec) + return ehdr->e_type != ET_REL; + + assert (reloc_map_table[type].appear == both); + return true; +} + + +/* Check for the simple reloc types. */ +Elf_Type +ppc64_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type) +{ + switch (type) + { + case R_PPC64_ADDR64: + case R_PPC64_UADDR64: + return ELF_T_XWORD; + case R_PPC64_ADDR32: + case R_PPC64_UADDR32: + return ELF_T_WORD; + case R_PPC64_UADDR16: + return ELF_T_HALF; + default: + return ELF_T_NUM; + } +} + + +const char * +ppc64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_PPC64_GLINK: + return "PPC64_GLINK"; + case DT_PPC64_OPD: + return "PPC64_OPD"; + case DT_PPC64_OPDSZ: + return "PPC64_OPDSZ"; + default: + break; + } + return NULL; +} + +/* Check whether given relocation is a copy relocation. */ +bool +ppc64_copy_reloc_p (int reloc) +{ + return reloc == R_PPC64_COPY; +} diff --git a/libebl/ppc_destr.c b/libebl/ppc_destr.c new file mode 100644 index 00000000..65bb81cc --- /dev/null +++ b/libebl/ppc_destr.c @@ -0,0 +1,27 @@ +/* Destructor for PPC specific backend library. + 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 + 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_ppc.h> + + +void +ppc_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/ppc_init.c b/libebl/ppc_init.c new file mode 100644 index 00000000..4d72c46d --- /dev/null +++ b/libebl/ppc_init.c @@ -0,0 +1,43 @@ +/* Initialization of PPC specific backend library. + 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 + 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_ppc.h> + + +const char * +ppc_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 NULL; + + /* We handle it. */ + eh->name = "PowerPC"; + eh->reloc_type_name = ppc_reloc_type_name; + 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->copy_reloc_p = ppc_copy_reloc_p; + eh->destr = ppc_destr; + + return MODVERSION; +} diff --git a/libebl/ppc_symbol.c b/libebl/ppc_symbol.c new file mode 100644 index 00000000..20beae31 --- /dev/null +++ b/libebl/ppc_symbol.c @@ -0,0 +1,174 @@ +/* PPC specific symbolic name handling. + 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 + 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 <elf.h> +#include <stddef.h> + +#include <libebl_ppc.h> + + +/* Return of the backend. */ +const char * +ppc_backend_name (void) +{ + return "ppc"; +} + + +/* Relocation mapping table. */ +static struct +{ + const char *name; + enum { both = 0, rel = 1, exec = 2 } appear; +} reloc_map_table[] = + { + // XXX Check all the appear values. + [R_PPC_NONE] = { "R_PPC_NONE", both }, + [R_PPC_ADDR32] = { "R_PPC_ADDR32", both }, + [R_PPC_ADDR24] = { "R_PPC_ADDR24", both }, + [R_PPC_ADDR16] = { "R_PPC_ADDR16", both }, + [R_PPC_ADDR16_LO] = { "R_PPC_ADDR16_LO", both }, + [R_PPC_ADDR16_HI] = { "R_PPC_ADDR16_HI", both }, + [R_PPC_ADDR16_HA] = { "R_PPC_ADDR16_HA", both }, + [R_PPC_ADDR14] = { "R_PPC_ADDR14", exec }, + [R_PPC_ADDR14_BRTAKEN] = { "R_PPC_ADDR14_BRTAKEN", exec }, + [R_PPC_ADDR14_BRNTAKEN] = { "R_PPC_ADDR14_BRNTAKEN", exec }, + [R_PPC_REL24] = { "R_PPC_REL24", both }, + [R_PPC_REL14] = { "R_PPC_REL14", both }, + [R_PPC_REL14_BRTAKEN] = { "R_PPC_REL14_BRTAKEN", exec }, + [R_PPC_REL14_BRNTAKEN] = { "R_PPC_REL14_BRNTAKEN", exec }, + [R_PPC_GOT16] = { "R_PPC_GOT16", rel }, + [R_PPC_GOT16_LO] = { "R_PPC_GOT16_LO", rel }, + [R_PPC_GOT16_HI] = { "R_PPC_GOT16_HI", rel }, + [R_PPC_GOT16_HA] = { "R_PPC_GOT16_HA", rel }, + [R_PPC_PLTREL24] = { "R_PPC_PLTREL24", rel }, + [R_PPC_COPY] = { "R_PPC_COPY", exec }, + [R_PPC_GLOB_DAT] = { "R_PPC_GLOB_DAT", exec }, + [R_PPC_JMP_SLOT] = { "R_PPC_JMP_SLOT", exec }, + [R_PPC_RELATIVE] = { "R_PPC_RELATIVE", exec }, + [R_PPC_LOCAL24PC] = { "R_PPC_LOCAL24PC", rel }, + [R_PPC_UADDR32] = { "R_PPC_UADDR32", exec }, + [R_PPC_UADDR16] = { "R_PPC_UADDR16", exec }, + [R_PPC_REL32] = { "R_PPC_REL32", exec }, + [R_PPC_PLT32] = { "R_PPC_PLT32", exec }, + [R_PPC_PLTREL32] = { "R_PPC_PLTREL32", both }, + [R_PPC_PLT16_LO] = { "R_PPC_PLT16_LO", both }, + [R_PPC_PLT16_HI] = { "R_PPC_PLT16_HI", both }, + [R_PPC_PLT16_HA] = { "R_PPC_PLT16_HA", both }, + [R_PPC_SDAREL16] = { "R_PPC_SDAREL16", both }, + [R_PPC_SECTOFF] = { "R_PPC_SECTOFF", both }, + [R_PPC_SECTOFF_LO] = { "R_PPC_SECTOFF_LO", both }, + [R_PPC_SECTOFF_HI] = { "R_PPC_SECTOFF_HI", both }, + [R_PPC_SECTOFF_HA] = { "R_PPC_SECTOFF_HA", both }, + [R_PPC_TLS] = { "R_PPC_TLS", both }, + [R_PPC_DTPMOD32] = { "R_PPC_DTPMOD32", exec }, + [R_PPC_TPREL16] = { "R_PPC_TPREL16", rel }, + [R_PPC_TPREL16_LO] = { "R_PPC_TPREL16_LO", rel }, + [R_PPC_TPREL16_HI] = { "R_PPC_TPREL16_HI", rel }, + [R_PPC_TPREL16_HA] = { "R_PPC_TPREL16_HA", rel }, + [R_PPC_TPREL32] = { "R_PPC_TPREL32", exec }, + [R_PPC_DTPREL16] = { "R_PPC_DTPREL16", rel }, + [R_PPC_DTPREL16_LO] = { "R_PPC_DTPREL16_LO", rel }, + [R_PPC_DTPREL16_HI] = { "R_PPC_DTPREL16_HI", rel }, + [R_PPC_DTPREL16_HA] = { "R_PPC_DTPREL16_HA", rel }, + [R_PPC_DTPREL32] = { "R_PPC_DTPREL32", exec }, + [R_PPC_GOT_TLSGD16] = { "R_PPC_GOT_TLSGD16", exec }, + [R_PPC_GOT_TLSGD16_LO] = { "R_PPC_GOT_TLSGD16_LO", exec }, + [R_PPC_GOT_TLSGD16_HI] = { "R_PPC_GOT_TLSGD16_HI", exec }, + [R_PPC_GOT_TLSGD16_HA] = { "R_PPC_GOT_TLSGD16_HA", exec }, + [R_PPC_GOT_TLSLD16] = { "R_PPC_GOT_TLSLD16", exec }, + [R_PPC_GOT_TLSLD16_LO] = { "R_PPC_GOT_TLSLD16_LO", exec }, + [R_PPC_GOT_TLSLD16_HI] = { "R_PPC_GOT_TLSLD16_HI", exec }, + [R_PPC_GOT_TLSLD16_HA] = { "R_PPC_GOT_TLSLD16_HA", exec }, + [R_PPC_GOT_TPREL16] = { "R_PPC_GOT_TPREL16", exec }, + [R_PPC_GOT_TPREL16_LO] = { "R_PPC_GOT_TPREL16_LO", exec }, + [R_PPC_GOT_TPREL16_HI] = { "R_PPC_GOT_TPREL16_HI", exec }, + [R_PPC_GOT_TPREL16_HA] = { "R_PPC_GOT_TPREL16_HA", exec }, + [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 } + }; + + +/* Determine relocation type string for PPC. */ +const char * +ppc_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type < 0 || type >= R_PPC_NUM) + return NULL; + + return reloc_map_table[type].name; +} + + +/* Check for correct relocation type. */ +bool +ppc_reloc_type_check (int type) +{ + return (type >= R_PPC_NONE && type < R_PPC_NUM + && reloc_map_table[type].name != NULL) ? true : false; +} + + +/* Check for correct relocation type use. */ +bool +ppc_reloc_valid_use (Elf *elf, int type) +{ + if (type < R_PPC_NONE || type >= R_PPC_NUM + || reloc_map_table[type].name == NULL) + return false; + + Elf32_Ehdr *ehdr = elf32_getehdr (elf); + assert (ehdr != NULL); + + if (reloc_map_table[type].appear == rel) + return ehdr->e_type == ET_REL; + + if (reloc_map_table[type].appear == exec) + return ehdr->e_type != ET_REL; + + assert (reloc_map_table[type].appear == both); + return true; +} + + +/* Check for the simple reloc types. */ +Elf_Type +ppc_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type) +{ + switch (type) + { + case R_PPC_ADDR32: + case R_PPC_UADDR32: + return ELF_T_WORD; + case R_PPC_UADDR16: + return ELF_T_HALF; + default: + return ELF_T_NUM; + } +} + +/* Check whether given relocation is a copy relocation. */ +bool +ppc_copy_reloc_p (int reloc) +{ + return reloc == R_PPC_COPY; +} diff --git a/libebl/sh_destr.c b/libebl/sh_destr.c new file mode 100644 index 00000000..4f065343 --- /dev/null +++ b/libebl/sh_destr.c @@ -0,0 +1,27 @@ +/* Destructor for SH specific backend library. + 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 + 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_sh.h> + + +void +sh_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/sh_init.c b/libebl/sh_init.c new file mode 100644 index 00000000..bb6c9040 --- /dev/null +++ b/libebl/sh_init.c @@ -0,0 +1,40 @@ +/* Initialization of SH 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_sh.h> + + +const char * +sh_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 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 MODVERSION; +} diff --git a/libebl/sh_symbol.c b/libebl/sh_symbol.c new file mode 100644 index 00000000..e24fff15 --- /dev/null +++ b/libebl/sh_symbol.c @@ -0,0 +1,99 @@ +/* SH specific relocation 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_sh.h> + + +/* Return of the backend. */ +const char * +sh_backend_name (void) +{ + return "sh"; +} + + +/* Determine relocation type string for SH. */ +const char * +sh_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + static const char *map_table1[] = + { + [R_SH_NONE] = "R_SH_NONE", + [R_SH_DIR32] = "R_SH_DIR32", + [R_SH_REL32] = "R_SH_REL32", + [R_SH_DIR8WPN] = "R_SH_DIR8WPN", + [R_SH_IND12W] = "R_SH_IND12W", + [R_SH_DIR8WPL] = "R_SH_DIR8WPL", + [R_SH_DIR8WPZ] = "R_SH_DIR8WPZ", + [R_SH_DIR8BP] = "R_SH_DIR8BP", + [R_SH_DIR8W] = "R_SH_DIR8W", + [R_SH_DIR8L] = "R_SH_DIR8L", + [R_SH_SWITCH16] = "R_SH_SWITCH16", + [R_SH_SWITCH32] = "R_SH_SWITCH32", + [R_SH_USES] = "R_SH_USES", + [R_SH_COUNT] = "R_SH_COUNT", + [R_SH_ALIGN] = "R_SH_ALIGN", + [R_SH_CODE] = "R_SH_CODE", + [R_SH_DATA] = "R_SH_DATA", + [R_SH_LABEL] = "R_SH_LABEL", + [R_SH_SWITCH8] = "R_SH_SWITCH8", + [R_SH_GNU_VTINHERIT] ="R_SH_GNU_VTINHERIT", + [R_SH_GNU_VTENTRY] = "R_SH_GNU_VTENTRY" + }; + static const char *map_table2[] = + { + [R_SH_TLS_GD_32] = "R_SH_TLS_GD_32", + [R_SH_TLS_LD_32] = "R_SH_TLS_LD_32", + [R_SH_TLS_LDO_32] = "R_SH_TLS_LDO_32", + [R_SH_TLS_IE_32] = "R_SH_TLS_IE_32", + [R_SH_TLS_LE_32] = "R_SH_TLS_LE_32", + [R_SH_TLS_DTPMOD32] = "R_SH_TLS_DTPMOD32", + [R_SH_TLS_DTPOFF32] = "R_SH_TLS_DTPOFF32", + [R_SH_TLS_TPOFF32] = "R_SH_TLS_TPOFF32", + [R_SH_GOT32 - R_SH_GOT32] = "R_SH_GOT32", + [R_SH_PLT32 - R_SH_GOT32] = "R_SH_PLT32", + [R_SH_COPY - R_SH_GOT32] = "R_SH_COPY", + [R_SH_GLOB_DAT - R_SH_GOT32] = "R_SH_GLOB_DAT", + [R_SH_JMP_SLOT - R_SH_GOT32] = "R_SH_JMP_SLOT", + [R_SH_RELATIVE - R_SH_GOT32] = "R_SH_RELATIVE", + [R_SH_GOTOFF - R_SH_GOT32] = "R_SH_GOTOFF", + [R_SH_GOTPC - R_SH_GOT32] = "R_SH_GOTPC" + }; + + if (type >= 0 + && (size_t) type < sizeof (map_table1) / sizeof (map_table1[0])) + return map_table1[type]; + + if ((type - R_SH_TLS_GD_32) >= 0 + && ((size_t) (type - R_SH_TLS_GD_32) + < sizeof (map_table2) / sizeof (map_table2[0]))) + return map_table2[type - R_SH_TLS_GD_32]; + + 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/libebl/sparc_destr.c b/libebl/sparc_destr.c new file mode 100644 index 00000000..819f3616 --- /dev/null +++ b/libebl/sparc_destr.c @@ -0,0 +1,26 @@ +/* Destructor for SPARC specific backend library. + 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 + 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_sparc.h> + + +void +sparc_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/sparc_init.c b/libebl/sparc_init.c new file mode 100644 index 00000000..ac461a10 --- /dev/null +++ b/libebl/sparc_init.c @@ -0,0 +1,46 @@ +/* Initialization of SPARC specific backend library. + 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 + 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_sparc.h> + + +const char * +sparc_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 NULL; + + /* We handle it. */ + if (machine == EM_SPARCV9) + eh->name = "SPARC v9"; + else if (machine == EM_SPARC32PLUS) + eh->name = "SPARC v8+"; + else + eh->name = "SPARC"; + 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 MODVERSION; +} diff --git a/libebl/sparc_symbol.c b/libebl/sparc_symbol.c new file mode 100644 index 00000000..f33ed537 --- /dev/null +++ b/libebl/sparc_symbol.c @@ -0,0 +1,149 @@ +/* SPARC specific symbolic name handling. + Copyright (C) 2002, 2003, 2005 Red Hat, Inc. + Written by Jakub Jelinek <jakub@redhat.com>, 2002. + + 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_sparc.h> + + +/* Return of the backend. */ +const char * +sparc_backend_name (void) +{ + return "sparc"; +} + + +/* Relocation mapping table. */ +static const char *reloc_map_table[] = + { + [R_SPARC_NONE] = "R_SPARC_NONE", + [R_SPARC_8] = "R_SPARC_8", + [R_SPARC_16] = "R_SPARC_16", + [R_SPARC_32] = "R_SPARC_32", + [R_SPARC_DISP8] = "R_SPARC_DISP8", + [R_SPARC_DISP16] = "R_SPARC_DISP16", + [R_SPARC_DISP32] = "R_SPARC_DISP32", + [R_SPARC_WDISP30] = "R_SPARC_WDISP30", + [R_SPARC_WDISP22] = "R_SPARC_WDISP22", + [R_SPARC_HI22] = "R_SPARC_HI22", + [R_SPARC_22] = "R_SPARC_22", + [R_SPARC_13] = "R_SPARC_13", + [R_SPARC_LO10] = "R_SPARC_LO10", + [R_SPARC_GOT10] = "R_SPARC_GOT10", + [R_SPARC_GOT13] = "R_SPARC_GOT13", + [R_SPARC_GOT22] = "R_SPARC_GOT22", + [R_SPARC_PC10] = "R_SPARC_PC10", + [R_SPARC_PC22] = "R_SPARC_PC22", + [R_SPARC_WPLT30] = "R_SPARC_WPLT30", + [R_SPARC_COPY] = "R_SPARC_COPY", + [R_SPARC_GLOB_DAT] = "R_SPARC_GLOB_DAT", + [R_SPARC_JMP_SLOT] = "R_SPARC_JMP_SLOT", + [R_SPARC_RELATIVE] = "R_SPARC_RELATIVE", + [R_SPARC_UA32] = "R_SPARC_UA32", + [R_SPARC_PLT32] = "R_SPARC_PLT32", + [R_SPARC_HIPLT22] = "R_SPARC_HIPLT22", + [R_SPARC_LOPLT10] = "R_SPARC_LOPLT10", + [R_SPARC_PCPLT32] = "R_SPARC_PCPLT32", + [R_SPARC_PCPLT22] = "R_SPARC_PCPLT22", + [R_SPARC_PCPLT10] = "R_SPARC_PCPLT10", + [R_SPARC_10] = "R_SPARC_10", + [R_SPARC_11] = "R_SPARC_11", + [R_SPARC_64] = "R_SPARC_64", + [R_SPARC_OLO10] = "R_SPARC_OLO10", + [R_SPARC_HH22] = "R_SPARC_HH22", + [R_SPARC_HM10] = "R_SPARC_HM10", + [R_SPARC_LM22] = "R_SPARC_LM22", + [R_SPARC_PC_HH22] = "R_SPARC_PC_HH22", + [R_SPARC_PC_HM10] = "R_SPARC_PC_HM10", + [R_SPARC_PC_LM22] = "R_SPARC_PC_LM22", + [R_SPARC_WDISP16] = "R_SPARC_WDISP16", + [R_SPARC_WDISP19] = "R_SPARC_WDISP19", + [R_SPARC_7] = "R_SPARC_7", + [R_SPARC_5] = "R_SPARC_5", + [R_SPARC_6] = "R_SPARC_6", + [R_SPARC_DISP64] = "R_SPARC_DISP64", + [R_SPARC_PLT64] = "R_SPARC_PLT64", + [R_SPARC_HIX22] = "R_SPARC_HIX22", + [R_SPARC_LOX10] = "R_SPARC_LOX10", + [R_SPARC_H44] = "R_SPARC_H44", + [R_SPARC_M44] = "R_SPARC_M44", + [R_SPARC_L44] = "R_SPARC_L44", + [R_SPARC_REGISTER] = "R_SPARC_REGISTER", + [R_SPARC_UA64] = "R_SPARC_UA64", + [R_SPARC_UA16] = "R_SPARC_UA16", + [R_SPARC_TLS_GD_HI22] = "R_SPARC_TLS_GD_HI22", + [R_SPARC_TLS_GD_LO10] = "R_SPARC_TLS_GD_LO10", + [R_SPARC_TLS_GD_ADD] = "R_SPARC_TLS_GD_ADD", + [R_SPARC_TLS_GD_CALL] = "R_SPARC_TLS_GD_CALL", + [R_SPARC_TLS_LDM_HI22] = "R_SPARC_TLS_LDM_HI22", + [R_SPARC_TLS_LDM_LO10] = "R_SPARC_TLS_LDM_LO10", + [R_SPARC_TLS_LDM_ADD] = "R_SPARC_TLS_LDM_ADD", + [R_SPARC_TLS_LDM_CALL] = "R_SPARC_TLS_LDM_CALL", + [R_SPARC_TLS_LDO_HIX22] = "R_SPARC_TLS_LDO_HIX22", + [R_SPARC_TLS_LDO_LOX10] = "R_SPARC_TLS_LDO_LOX10", + [R_SPARC_TLS_LDO_ADD] = "R_SPARC_TLS_LDO_ADD", + [R_SPARC_TLS_IE_HI22] = "R_SPARC_TLS_IE_HI22", + [R_SPARC_TLS_IE_LO10] = "R_SPARC_TLS_IE_LO10", + [R_SPARC_TLS_IE_LD] = "R_SPARC_TLS_IE_LD", + [R_SPARC_TLS_IE_LDX] = "R_SPARC_TLS_IE_LDX", + [R_SPARC_TLS_IE_ADD] = "R_SPARC_TLS_IE_ADD", + [R_SPARC_TLS_LE_HIX22] = "R_SPARC_TLS_LE_HIX22", + [R_SPARC_TLS_LE_LOX10] = "R_SPARC_TLS_LE_LOX10", + [R_SPARC_TLS_DTPMOD32] = "R_SPARC_TLS_DTPMOD32", + [R_SPARC_TLS_DTPMOD64] = "R_SPARC_TLS_DTPMOD64", + [R_SPARC_TLS_DTPOFF32] = "R_SPARC_TLS_DTPOFF32", + [R_SPARC_TLS_DTPOFF64] = "R_SPARC_TLS_DTPOFF64", + [R_SPARC_TLS_TPOFF32] = "R_SPARC_TLS_TPOFF32", + [R_SPARC_TLS_TPOFF64] = "R_SPARC_TLS_TPOFF64" + }; + + +/* Determine relocation type string for sparc. */ +const char * +sparc_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + /* High 24 bits of r_type are used for second addend in R_SPARC_OLO10. */ + if ((type & 0xff) == R_SPARC_OLO10) + return reloc_map_table[type & 0xff]; + + if (type < 0 || type >= R_SPARC_NUM) + return NULL; + + return reloc_map_table[type]; +} + + +/* Check for correct relocation type. */ +bool +sparc_reloc_type_check (int type) +{ + if ((type & 0xff) == R_SPARC_OLO10) + return true; + 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/libebl/x86_64_corenote.c b/libebl/x86_64_corenote.c new file mode 100644 index 00000000..0ee7ceae --- /dev/null +++ b/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/libebl/x86_64_destr.c b/libebl/x86_64_destr.c new file mode 100644 index 00000000..38058299 --- /dev/null +++ b/libebl/x86_64_destr.c @@ -0,0 +1,27 @@ +/* Destructor for x86_64 specific backend library. + 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 + 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_x86_64.h> + + +void +x86_64_destr (bh) + Ebl *bh __attribute__ ((unused)); +{ + /* Nothing to do so far. */ +} diff --git a/libebl/x86_64_init.c b/libebl/x86_64_init.c new file mode 100644 index 00000000..655a67fb --- /dev/null +++ b/libebl/x86_64_init.c @@ -0,0 +1,44 @@ +/* Initialization of x86-64 specific backend library. + 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 + 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_x86_64.h> + + +const char * +x86_64_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 NULL; + + /* We handle it. */ + eh->name = "AMD x86-64"; + eh->reloc_type_name = x86_64_reloc_type_name; + 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 = x86_64_core_note; + eh->copy_reloc_p = x86_64_copy_reloc_p; + eh->destr = x86_64_destr; + + return MODVERSION; +} diff --git a/libebl/x86_64_symbol.c b/libebl/x86_64_symbol.c new file mode 100644 index 00000000..38d357cb --- /dev/null +++ b/libebl/x86_64_symbol.c @@ -0,0 +1,136 @@ +/* x86_64 specific symbolic name handling. + 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 + 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 <elf.h> +#include <stddef.h> + +#include <libebl_x86_64.h> + + +/* Return of the backend. */ +const char * +x86_64_backend_name (void) +{ + return "x86-64"; +} + + +/* Relocation mapping table. */ +static struct +{ + const char *name; + enum { both = 0, rel = 1, exec = 2 } appear; +} reloc_map_table[] = + { + [R_X86_64_NONE] = { "R_X86_64_NONE", both }, + [R_X86_64_64] = { "R_X86_64_64", both }, + [R_X86_64_PC32] = { "R_X86_64_PC32", rel }, + [R_X86_64_GOT32] = { "R_X86_64_GOT32", rel }, + [R_X86_64_PLT32] = { "R_X86_64_PLT32", rel }, + [R_X86_64_COPY] = { "R_X86_64_COPY", exec }, + [R_X86_64_GLOB_DAT] = { "R_X86_64_GLOB_DAT", exec }, + [R_X86_64_JUMP_SLOT] = { "R_X86_64_JUMP_SLOT", exec }, + [R_X86_64_RELATIVE] = { "R_X86_64_RELATIVE", exec }, + [R_X86_64_GOTPCREL] = { "R_X86_64_GOTPCREL", exec }, + [R_X86_64_32] = { "R_X86_64_32", both }, + [R_X86_64_32S] = { "R_X86_64_32S", rel }, + [R_X86_64_16] = { "R_X86_64_16", rel }, + [R_X86_64_PC16] = { "R_X86_64_PC16", rel }, + [R_X86_64_8] = { "R_X86_64_8", rel }, + [R_X86_64_PC8] = { "R_X86_64_PC8", rel }, + [R_X86_64_DTPMOD64] = { "R_X86_64_DTPMOD64", rel }, + [R_X86_64_DTPOFF64] = { "R_X86_64_DTPOFF64", rel }, + [R_X86_64_TPOFF64] = { "R_X86_64_TPOFF64", rel }, + [R_X86_64_TLSGD] = { "R_X86_64_TLSGD", rel }, + [R_X86_64_TLSLD] = { "R_X86_64_TLSLD", rel }, + [R_X86_64_DTPOFF32] = { "R_X86_64_DTPOFF32", rel }, + [R_X86_64_GOTTPOFF] = { "R_X86_64_GOTTPOFF", rel }, + [R_X86_64_TPOFF32] = { "R_X86_64_TPOFF32", rel } + }; + + +/* Determine relocation type string for x86-64. */ +const char * +x86_64_reloc_type_name (int type, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type < 0 || type >= R_X86_64_NUM) + return NULL; + + return reloc_map_table[type].name; +} + + +/* Check for correct relocation type. */ +bool +x86_64_reloc_type_check (int type) +{ + return (type >= R_X86_64_NONE && type < R_X86_64_NUM + && reloc_map_table[type].name != NULL) ? true : false; +} + + +/* Check for correct relocation type use. */ +bool +x86_64_reloc_valid_use (Elf *elf, int type) +{ + if (type < R_X86_64_NONE || type >= R_X86_64_NUM + || reloc_map_table[type].name == NULL) + return false; + + Elf64_Ehdr *ehdr = elf64_getehdr (elf); + assert (ehdr != NULL); + + if (reloc_map_table[type].appear == rel) + return ehdr->e_type == ET_REL; + + if (reloc_map_table[type].appear == exec) + return ehdr->e_type != ET_REL; + + assert (reloc_map_table[type].appear == both); + return true; +} + +/* Check for the simple reloc types. */ +Elf_Type +x86_64_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type) +{ + switch (type) + { + case R_X86_64_64: + return ELF_T_XWORD; + case R_X86_64_32: + return ELF_T_WORD; + case R_X86_64_32S: + return ELF_T_SWORD; + case R_X86_64_16: + return ELF_T_HALF; + case R_X86_64_8: + return ELF_T_BYTE; + default: + 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; +} |