diff options
Diffstat (limited to 'trunk/gelf')
-rw-r--r-- | trunk/gelf/Makefile.am | 13 | ||||
-rw-r--r-- | trunk/gelf/Makefile.in | 345 | ||||
-rw-r--r-- | trunk/gelf/gelf.c | 573 | ||||
-rw-r--r-- | trunk/gelf/gelf.h | 72 |
4 files changed, 1003 insertions, 0 deletions
diff --git a/trunk/gelf/Makefile.am b/trunk/gelf/Makefile.am new file mode 100644 index 0000000..f6320fa --- /dev/null +++ b/trunk/gelf/Makefile.am @@ -0,0 +1,13 @@ +## Process this file with automake to create Makefile.in + +AUTOMAKE_OPTIONS = 1.4 gnu + +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -Wall +AM_CFLAGS = -Wall +INCLUDES = @GELFINCLUDE@ + +noinst_LTLIBRARIES = libgelf.la + +libgelf_la_SOURCES = gelf.c + +noinst_HEADERS = gelf.h diff --git a/trunk/gelf/Makefile.in b/trunk/gelf/Makefile.in new file mode 100644 index 0000000..05f9925 --- /dev/null +++ b/trunk/gelf/Makefile.in @@ -0,0 +1,345 @@ +# Makefile.in generated by automake 1.6.3 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ + +EXEEXT = @EXEEXT@ +OBJEXT = @OBJEXT@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AWK = @AWK@ +CC = @CC@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +EGREP = @EGREP@ +F77 = @F77@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GELFINCLUDE = @GELFINCLUDE@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LIBGELF = @LIBGELF@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +RC = @RC@ +STRIP = @STRIP@ +VERSION = @VERSION@ +am__include = @am__include@ +am__quote = @am__quote@ +install_sh = @install_sh@ + +AUTOMAKE_OPTIONS = 1.4 gnu + +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -Wall +AM_CFLAGS = -Wall +INCLUDES = @GELFINCLUDE@ + +noinst_LTLIBRARIES = libgelf.la + +libgelf_la_SOURCES = gelf.c + +noinst_HEADERS = gelf.h +subdir = gelf +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) + +libgelf_la_LDFLAGS = +libgelf_la_LIBADD = +am_libgelf_la_OBJECTS = gelf.lo +libgelf_la_OBJECTS = $(am_libgelf_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gelf.Plo +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CFLAGS = @CFLAGS@ +DIST_SOURCES = $(libgelf_la_SOURCES) +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in +SOURCES = $(libgelf_la_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu gelf/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test -z "$dir" && dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgelf.la: $(libgelf_la_OBJECTS) $(libgelf_la_DEPENDENCIES) + $(LINK) $(libgelf_la_LDFLAGS) $(libgelf_la_OBJECTS) $(libgelf_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf.Plo@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `cygpath -w $<` + +.c.lo: +@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< +CCDEPMODE = @CCDEPMODE@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ETAGS = etags +ETAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @list='$(DISTFILES)'; for file in $$list; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +uninstall-am: uninstall-info-am + +.PHONY: GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool tags uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/trunk/gelf/gelf.c b/trunk/gelf/gelf.c new file mode 100644 index 0000000..915cf5b --- /dev/null +++ b/trunk/gelf/gelf.c @@ -0,0 +1,573 @@ +/* Generic ELF wrapper for libelf which does not support gelf_ API. + Copyright (C) 2001, 2002, 2004 Red Hat, Inc. + Written by Jakub Jelinek <jakub@redhat.com>, 2001. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <config.h> +#include <elf.h> +#include <libelf.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include "gelf.h" + +inline int +gelf_getclass (Elf *elf) +{ + size_t size; + char *e_ident = elf_getident (elf, &size); + + if (e_ident == NULL) + return ELFCLASSNONE; + switch (e_ident [EI_CLASS]) + { + case ELFCLASS32: + case ELFCLASS64: + return e_ident [EI_CLASS]; + default: + return ELFCLASSNONE; + } +} + +size_t +gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int ver) +{ + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + return elf32_fsize (type, count, ver); + case ELFCLASS64: + return elf64_fsize (type, count, ver); + default: + return 0; + } +} + +GElf_Ehdr * +gelf_getehdr (Elf *elf, GElf_Ehdr *dst) +{ + Elf32_Ehdr *ehdr32; + Elf64_Ehdr *ehdr64; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + ehdr32 = elf32_getehdr (elf); + if (ehdr32 != NULL) + { + memcpy (dst->e_ident, ehdr32->e_ident, EI_NIDENT); + dst->e_type = ehdr32->e_type; + dst->e_machine = ehdr32->e_machine; + dst->e_version = ehdr32->e_version; + dst->e_entry = ehdr32->e_entry; + dst->e_phoff = ehdr32->e_phoff; + dst->e_shoff = ehdr32->e_shoff; + dst->e_flags = ehdr32->e_flags; + dst->e_ehsize = ehdr32->e_ehsize; + dst->e_phentsize = ehdr32->e_phentsize; + dst->e_phnum = ehdr32->e_phnum; + dst->e_shentsize = ehdr32->e_shentsize; + dst->e_shnum = ehdr32->e_shnum; + dst->e_shstrndx = ehdr32->e_shstrndx; + return dst; + } + break; + case ELFCLASS64: + ehdr64 = elf64_getehdr (elf); + if (ehdr64 != NULL) + { + memcpy (dst, ehdr64, sizeof (Elf64_Ehdr)); + return dst; + } + } + return NULL; +} + +int +gelf_update_ehdr (Elf *elf, GElf_Ehdr *src) +{ + Elf32_Ehdr *ehdr32; + Elf64_Ehdr *ehdr64; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + ehdr32 = elf32_getehdr (elf); + if (ehdr32 == NULL) + return 0; + memcpy (ehdr32->e_ident, src->e_ident, EI_NIDENT); + ehdr32->e_type = src->e_type; + ehdr32->e_machine = src->e_machine; + ehdr32->e_version = src->e_version; + ehdr32->e_entry = src->e_entry; + ehdr32->e_phoff = src->e_phoff; + ehdr32->e_shoff = src->e_shoff; + ehdr32->e_flags = src->e_flags; + ehdr32->e_ehsize = src->e_ehsize; + ehdr32->e_phentsize = src->e_phentsize; + ehdr32->e_phnum = src->e_phnum; + ehdr32->e_shentsize = src->e_shentsize; + ehdr32->e_shnum = src->e_shnum; + ehdr32->e_shstrndx = src->e_shstrndx; + return 1; + case ELFCLASS64: + ehdr64 = elf64_getehdr (elf); + if (ehdr64 != NULL) + { + memcpy (ehdr64, src, sizeof (Elf64_Ehdr)); + return 1; + } + default: + break; + } + return 0; +} + +unsigned long +gelf_newehdr (Elf *elf, int class) +{ + switch (class) + { + case ELFCLASS32: + return (unsigned long) elf32_newehdr (elf); + case ELFCLASS64: + return (unsigned long) elf64_newehdr (elf); + default: + return 0; + } +} + +GElf_Phdr * +gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst) +{ + Elf32_Ehdr *ehdr32; + Elf64_Ehdr *ehdr64; + Elf32_Phdr *phdr32; + Elf64_Phdr *phdr64; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + phdr32 = elf32_getphdr (elf); + if (phdr32 == NULL) + return NULL; + ehdr32 = elf32_getehdr (elf); + if (ehdr32 == NULL) + return NULL; + if (ndx >= ehdr32->e_phnum) + return NULL; + phdr32 += ndx; + dst->p_type = phdr32->p_type; + dst->p_offset = phdr32->p_offset; + dst->p_vaddr = phdr32->p_vaddr; + dst->p_paddr = phdr32->p_paddr; + dst->p_filesz = phdr32->p_filesz; + dst->p_memsz = phdr32->p_memsz; + dst->p_flags = phdr32->p_flags; + dst->p_align = phdr32->p_align; + return dst; + case ELFCLASS64: + phdr64 = elf64_getphdr (elf); + if (phdr64 == NULL) + return NULL; + ehdr64 = elf64_getehdr (elf); + if (ehdr64 == NULL) + return NULL; + if (ndx >= ehdr64->e_phnum) + return NULL; + memcpy (dst, phdr64 + ndx, sizeof (Elf64_Phdr)); + return dst; + default: + return NULL; + } +} + +int +gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src) +{ + Elf32_Ehdr *ehdr32; + Elf64_Ehdr *ehdr64; + Elf32_Phdr *phdr32; + Elf64_Phdr *phdr64; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + phdr32 = elf32_getphdr (elf); + if (phdr32 == NULL) + return 0; + ehdr32 = elf32_getehdr (elf); + if (ehdr32 == NULL) + return 0; + if (ndx >= ehdr32->e_phnum) + return 0; + phdr32 += ndx; + phdr32->p_type = src->p_type; + phdr32->p_offset = src->p_offset; + phdr32->p_vaddr = src->p_vaddr; + phdr32->p_paddr = src->p_paddr; + phdr32->p_filesz = src->p_filesz; + phdr32->p_memsz = src->p_memsz; + phdr32->p_flags = src->p_flags; + phdr32->p_align = src->p_align; + return 1; + case ELFCLASS64: + phdr64 = elf64_getphdr (elf); + if (phdr64 == NULL) + return 0; + ehdr64 = elf64_getehdr (elf); + if (ehdr64 == NULL) + return 0; + if (ndx >= ehdr64->e_phnum) + return 0; + memcpy (phdr64 + ndx, src, sizeof (Elf64_Phdr)); + return 1; + default: + return 0; + } +} + +unsigned long +gelf_newphdr (Elf *elf, size_t phnum) +{ + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + return (unsigned long) elf32_newphdr (elf, phnum); + case ELFCLASS64: + return (unsigned long) elf64_newphdr (elf, phnum); + default: + return 0; + } +} + +GElf_Shdr * +gelfx_getshdr (Elf *elf, Elf_Scn *scn, GElf_Shdr *dst) +{ + Elf32_Shdr *shdr32; + Elf64_Shdr *shdr64; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + shdr32 = elf32_getshdr (scn); + if (shdr32 == NULL) + return NULL; + dst->sh_name = shdr32->sh_name; + dst->sh_type = shdr32->sh_type; + dst->sh_flags = shdr32->sh_flags; + dst->sh_addr = shdr32->sh_addr; + dst->sh_offset = shdr32->sh_offset; + dst->sh_size = shdr32->sh_size; + dst->sh_link = shdr32->sh_link; + dst->sh_info = shdr32->sh_info; + dst->sh_addralign = shdr32->sh_addralign; + dst->sh_entsize = shdr32->sh_entsize; + return dst; + case ELFCLASS64: + shdr64 = elf64_getshdr (scn); + if (shdr64 == NULL) + return NULL; + memcpy (dst, shdr64, sizeof (Elf64_Shdr)); + return dst; + default: + return NULL; + } +} + +int +gelfx_update_shdr (Elf *elf, Elf_Scn *scn, GElf_Shdr *src) +{ + Elf32_Shdr *shdr32; + Elf64_Shdr *shdr64; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + shdr32 = elf32_getshdr (scn); + if (shdr32 == NULL) + return 0; + shdr32->sh_name = src->sh_name; + shdr32->sh_type = src->sh_type; + shdr32->sh_flags = src->sh_flags; + shdr32->sh_addr = src->sh_addr; + shdr32->sh_offset = src->sh_offset; + shdr32->sh_size = src->sh_size; + shdr32->sh_link = src->sh_link; + shdr32->sh_info = src->sh_info; + shdr32->sh_addralign = src->sh_addralign; + shdr32->sh_entsize = src->sh_entsize; + return 1; + case ELFCLASS64: + shdr64 = elf64_getshdr (scn); + if (shdr64 == NULL) + return 0; + memcpy (shdr64, src, sizeof (Elf64_Shdr)); + return 1; + default: + return 0; + } +} + +Elf_Data * +gelf_xlatetom (Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) +{ + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + return elf32_xlatetom (dst, src, encode); + case ELFCLASS64: + return elf64_xlatetom (dst, src, encode); + default: + return NULL; + } +} + +Elf_Data * +gelf_xlatetof (Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) +{ + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + return elf32_xlatetof (dst, src, encode); + case ELFCLASS64: + return elf64_xlatetof (dst, src, encode); + default: + return NULL; + } +} + +GElf_Sym *gelfx_getsym (Elf *elf, Elf_Data *data, int ndx, GElf_Sym *dst) +{ + Elf32_Sym *sym32; + + if (data->d_type != ELF_T_SYM) + return NULL; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size) + return NULL; + sym32 = &((Elf32_Sym *) data->d_buf)[ndx]; + dst->st_name = sym32->st_name; + dst->st_info = sym32->st_info; + dst->st_other = sym32->st_other; + dst->st_shndx = sym32->st_shndx; + dst->st_value = sym32->st_value; + dst->st_size = sym32->st_size; + return dst; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Sym) > data->d_size) + return NULL; + *dst = ((GElf_Sym *) data->d_buf)[ndx]; + return dst; + default: + return NULL; + } +} + +int gelfx_update_sym (Elf *elf, Elf_Data *data, int ndx, GElf_Sym *src) +{ + Elf32_Sym *sym32; + + if (data->d_type != ELF_T_SYM) + return 0; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size) + return 0; + sym32 = &((Elf32_Sym *) data->d_buf)[ndx]; + sym32->st_name = src->st_name; + sym32->st_info = src->st_info; + sym32->st_other = src->st_other; + sym32->st_shndx = src->st_shndx; + sym32->st_value = src->st_value; + sym32->st_size = src->st_size; + return 1; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Sym) > data->d_size) + return 0; + ((GElf_Sym *) data->d_buf)[ndx] = *src; + return 1; + default: + return 0; + } +} + +GElf_Dyn *gelfx_getdyn (Elf *elf, Elf_Data *data, int ndx, GElf_Dyn *dst) +{ + Elf32_Dyn *dyn32; + + if (data->d_type != ELF_T_DYN) + return NULL; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Dyn) > data->d_size) + return NULL; + dyn32 = &((Elf32_Dyn *) data->d_buf)[ndx]; + dst->d_tag = dyn32->d_tag; + dst->d_un.d_val = dyn32->d_un.d_val; + return dst; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Dyn) > data->d_size) + return NULL; + *dst = ((GElf_Dyn *) data->d_buf)[ndx]; + return dst; + default: + return NULL; + } +} + +int gelfx_update_dyn (Elf *elf, Elf_Data *data, int ndx, GElf_Dyn *src) +{ + Elf32_Dyn *dyn32; + + if (data->d_type != ELF_T_DYN) + return 0; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Dyn) > data->d_size) + return 0; + dyn32 = &((Elf32_Dyn *) data->d_buf)[ndx]; + dyn32->d_tag = src->d_tag; + dyn32->d_un.d_val = src->d_un.d_val; + return 1; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Dyn) > data->d_size) + return 0; + ((GElf_Dyn *) data->d_buf)[ndx] = *src; + return 1; + default: + return 0; + } +} + +GElf_Rel *gelfx_getrel (Elf *elf, Elf_Data *data, int ndx, GElf_Rel *dst) +{ + Elf32_Rel *rel32; + + if (data->d_type != ELF_T_REL) + return NULL; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Rel) > data->d_size) + return NULL; + rel32 = &((Elf32_Rel *) data->d_buf)[ndx]; + dst->r_offset = rel32->r_offset; + dst->r_info = GELF_R_INFO (ELF32_R_SYM (rel32->r_info), + ELF32_R_TYPE (rel32->r_info)); + return dst; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Rel) > data->d_size) + return NULL; + *dst = ((GElf_Rel *) data->d_buf)[ndx]; + return dst; + default: + return NULL; + } +} + +int gelfx_update_rel (Elf *elf, Elf_Data *data, int ndx, GElf_Rel *src) +{ + Elf32_Rel *rel32; + + if (data->d_type != ELF_T_REL) + return 0; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Rel) > data->d_size) + return 0; + rel32 = &((Elf32_Rel *) data->d_buf)[ndx]; + rel32->r_offset = src->r_offset; + rel32->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), + GELF_R_TYPE (src->r_info)); + return 1; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Rel) > data->d_size) + return 0; + ((GElf_Rel *) data->d_buf)[ndx] = *src; + return 1; + default: + return 0; + } +} + +GElf_Rela *gelfx_getrela (Elf *elf, Elf_Data *data, int ndx, GElf_Rela *dst) +{ + Elf32_Rela *rela32; + + if (data->d_type != ELF_T_RELA) + return NULL; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Rela) > data->d_size) + return NULL; + rela32 = &((Elf32_Rela *) data->d_buf)[ndx]; + dst->r_offset = rela32->r_offset; + dst->r_info = GELF_R_INFO (ELF32_R_SYM (rela32->r_info), + ELF32_R_TYPE (rela32->r_info)); + dst->r_addend = rela32->r_addend; + return dst; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Rela) > data->d_size) + return NULL; + *dst = ((GElf_Rela *) data->d_buf)[ndx]; + return dst; + default: + return NULL; + } +} + +int gelfx_update_rela (Elf *elf, Elf_Data *data, int ndx, GElf_Rela *src) +{ + Elf32_Rela *rela32; + + if (data->d_type != ELF_T_RELA) + return 0; + + switch (gelf_getclass (elf)) + { + case ELFCLASS32: + if ((ndx + 1) * sizeof (Elf32_Rela) > data->d_size) + return 0; + rela32 = &((Elf32_Rela *) data->d_buf)[ndx]; + rela32->r_offset = src->r_offset; + rela32->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), + GELF_R_TYPE (src->r_info)); + rela32->r_addend = src->r_addend; + return 1; + case ELFCLASS64: + if ((ndx + 1) * sizeof (Elf64_Rela) > data->d_size) + return 0; + ((GElf_Rela *) data->d_buf)[ndx] = *src; + return 1; + default: + return 0; + } +} diff --git a/trunk/gelf/gelf.h b/trunk/gelf/gelf.h new file mode 100644 index 0000000..6b76a15 --- /dev/null +++ b/trunk/gelf/gelf.h @@ -0,0 +1,72 @@ +/* Generic ELF wrapper for libelf which does not support gelf_ API. + Copyright (C) 2001 Red Hat, Inc. + Written by Jakub Jelinek <jakub@redhat.com>, 2001. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef GELF_H +#define GELF_H + +typedef Elf64_Half GElf_Half; +typedef Elf64_Word GElf_Word; +typedef Elf64_Sword GElf_Sword; +typedef Elf64_Xword GElf_Xword; +typedef Elf64_Sxword GElf_Sxword; +typedef Elf64_Addr GElf_Addr; +typedef Elf64_Off GElf_Off; +typedef Elf64_Ehdr GElf_Ehdr; +typedef Elf64_Shdr GElf_Shdr; +typedef Elf64_Section GElf_Section; +typedef Elf64_Sym GElf_Sym; +typedef Elf64_Rel GElf_Rel; +typedef Elf64_Rela GElf_Rela; +typedef Elf64_Phdr GElf_Phdr; +typedef Elf64_Dyn GElf_Dyn; +#define GELF_ST_BIND ELF64_ST_BIND +#define GELF_ST_TYPE ELF64_ST_TYPE +#define GELF_ST_INFO ELF64_ST_INFO +#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY +#define GELF_R_SYM ELF64_R_SYM +#define GELF_R_TYPE ELF64_R_TYPE +#define GELF_R_INFO ELF64_R_INFO + +extern int gelf_getclass (Elf *); +extern size_t gelf_fsize (Elf *, Elf_Type, size_t, unsigned); +extern GElf_Ehdr *gelf_getehdr (Elf *, GElf_Ehdr *); +extern int gelf_update_ehdr (Elf *, GElf_Ehdr *); +extern unsigned long gelf_newehdr (Elf *, int); +extern GElf_Phdr *gelf_getphdr (Elf *, int, GElf_Phdr *); +extern int gelf_update_phdr (Elf *, int, GElf_Phdr *); +extern unsigned long gelf_newphdr (Elf *, size_t); +extern Elf_Data *gelf_xlatetom (Elf *, Elf_Data *, const Elf_Data *, unsigned); +extern Elf_Data *gelf_xlatetof (Elf *, Elf_Data *, const Elf_Data *, unsigned); +/* The gelf_ equivalents of these functions only provide Elf_Scn resp. + Elf_Data pointers, without changing the underlying libelf implementation + it is either impossible to get Elf * pointer from that or it requires + internal knowledge about the libelf implementation. */ +extern GElf_Shdr *gelfx_getshdr (Elf *, Elf_Scn *, GElf_Shdr *); +extern int gelfx_update_shdr (Elf *, Elf_Scn *, GElf_Shdr *); +extern GElf_Sym *gelfx_getsym (Elf *, Elf_Data *, int, GElf_Sym *); +extern int gelfx_update_sym (Elf *, Elf_Data *, int, GElf_Sym *); +extern GElf_Dyn *gelfx_getdyn (Elf *, Elf_Data *, int, GElf_Dyn *); +extern int gelfx_update_dyn (Elf *, Elf_Data *, int, GElf_Dyn *); +extern GElf_Rel *gelfx_getrel (Elf *, Elf_Data *, int, GElf_Rel *); +extern GElf_Rela *gelfx_getrela (Elf *, Elf_Data *, int, GElf_Rela *); +extern int gelfx_update_rel (Elf *, Elf_Data *, int, GElf_Rel *); +extern int gelfx_update_rela (Elf *, Elf_Data *, int, GElf_Rela *); + +#define HAVE_GELFX_GETSHDR 1 + +#endif /* GELF_H */ |