diff options
Diffstat (limited to 'libelf')
129 files changed, 22859 insertions, 0 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog new file mode 100644 index 0000000..d88e2fe --- /dev/null +++ b/libelf/ChangeLog @@ -0,0 +1,786 @@ +2011-01-05 Jan Kratochvil <jan.kratochvil@redhat.com> + + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Fix off64_t overflow + when MAXIMUM_SIZE == ~0. + +2010-08-18 Roland McGrath <roland@redhat.com> + + * gelf_fsize.c (__libelf_type_sizes): Add entries for ELF_T_LIB + and ELF_T_GNUHASH. + Reported by Mark Hatle <mark.hatle@windriver.com>. + + * exttypes.h: Add cases for ElfNN_Lib. + Reported by Mark Hatle <mark.hatle@windriver.com>. + +2010-06-14 Ulrich Drepper <drepper@redhat.com> + + * gelf_update_shdr.c: Implicitly set ELF_F_DIRTY bit. + * gelf_update_phdr.c: Likewise. + * gelf_update_ehdr.c: Likewise. + +2010-04-14 Roland McGrath <roland@redhat.com> + + * elf32_getphdr.c: Check for e_phoff/size outside the file bounds. + * elf_begin.c (file_read_elf): Don't set .phdr here. + +2010-04-13 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2010-04-06 Roland McGrath <roland@redhat.com> + + * elf_error.c (ELF_E_FD_MISMATCH_IDX): Avoid nonobvious abbreviation + in error message. + +2010-04-01 Petr Machata <pmachata@redhat.com> + + * elf_getdata.c (__elf_getdata_rdlock): Initialize data.s for data + that do not need a conversion. + +2010-03-11 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2010-03-04 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update from glibc. + +2010-02-17 Roland McGrath <roland@redhat.com> + + * elf_begin.c (file_read_elf): Leave section rawdata_base and + data_base pointers null when [sh_offset,sh_size) points outside + the mapped file. + +2010-02-15 Roland McGrath <roland@redhat.com> + + * Makefile.am: Use config/eu.am for common stuff. + +2010-01-07 Roland McGrath <roland@redhat.com> + + * elf32_getphdr.c: Use __elf_getphdrnum_rdlock. + * gelf_getphdr.c: Likewise. + * gelf_update_phdr.c: Likewise. + * elf32_updatefile.c (__elf32_updatemmap, __elf32_updatefile): Likewise. + * elf32_updatenull.c (__elf32_updatenull_wrlock): Likewise. + * elf32_newphdr.c: Clear section 0's sh_info when resetting e_phnum. + If COUNT is too large, use store PN_XNUM instead and set sh_info. + * elf_begin.c (file_read_elf): Always allocate space we can use later + for section 0 if doing RDWR. + + * elf_getphdrnum.c: New file. + * Makefile.am (libelf_a_SOURCES): Add it. + * libelf.h: Declare elf_getphdrnum. + * libelfP.h: Declare __elf_getphdrnum_rdlock. + * libelf.map (ELFUTILS_1.6): New set, add elf_getphdrnum. + + * elf.h: Update from glibc. + +2009-10-23 Lubomir Rintel <lkundrak@v3.sk> + + * elf32_updatefile.c (fill_mmap): When starting past shdr_end, start + filling from section start, not shdr_end. + +2009-11-10 Roland McGrath <roland@redhat.com> + + * elf_readall.c (__libelf_readall): Fetch file size if not yet known. + +2009-11-06 Mark Wielaard <mjw@redhat.com> + + * elf_next.c (elf_next): Mark the archive header as unusable when + there is no next ar element. + +2009-08-12 Mark Wielaard <mjw@redhat.com> + + * Makefile.am (libelf.so): Use -Wl,-z,defs not -defs. + +2009-07-26 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update from glibc. + +2009-07-21 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c (__elfXX_updatemmap): Fix handling of gaps between + sections. Patch by Lubomir Rintel <lkundrak@v3.sk>. + +2009-07-08 Roland McGrath <roland@redhat.com> + + * libelfP.h (struct Elf): Remove unused ar.has_index field. + Reorder various members for optimal packing. + +2009-07-08 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update from glibc. + +2009-06-13 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (libelf_a_SOURCES): Replace elf_getshnum.c and + elf_getshstrndx.c with elf_getshdrnum.c and elf_getshdrstrndx.c. + * elf_getshnum.c: Renamed to... + * elf_getshdrnum.c: ...this. Rename function and add old name as + alias. Likewise for internal functions with derived names. + * elf_getshstrndx.c: Renamed to... + * elf_getshdrstrndx.c: ...this. Rename function and add old name as + alias. Likewise for internal functions with derived names. + * libelf.h: Add prototypes for new names. Make old names as + deprecated. + * libelfP.h: Rename internal function prototypes. + * libelf.map: Export for names. + * elf32_checksum.c: Don't use deprecated functions. + * elf32_getshdr.c: Likewise. + +2009-06-01 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update from glibc. + +2009-04-14 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2009-04-01 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2009-02-10 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c (updatefile): For the zeroth section we still + have to copy the section header. + +2009-02-01 Ulrich Drepper <drepper@redhat.com> + + * elf_strptr.c: Add comment re possible problem. + +2009-01-26 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatenull.c (updatenull_wrlock): Fix comment of + ELF_F_LAYOUT behaviour re section header table. + +2009-01-22 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c (__elfXX_updatemmap): Fill the gap between + sections even if only the section at the start of the gap has been + changed. + (__elfXX_updatefile): Likewise. + +2009-01-21 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c (__elfXX_updatemmap): Skip most of the loop to + handle sections for NOBITS sections. + (elfXX_updatefile): Likewise. + + * elf32_updatefile.c (__elfXX_updatemmap): When skipping non-NOBITS + sections we haven't loaded, update last_position based on scn_start, + not based on old value. Don't run the loop for the dummy section 0. + (elfXX_updatefile): Don't run the loop for the dummy section 0. + +2009-01-10 Ulrich Drepper <drepper@redhat.com> + + * libelfP.h (_): We only have one translation domain, elfutils. + + * Makefile.am: Use USE_LOCKS instead of USE_TLS. + * elf_error.c: Always use __thread. Remove all !USE_TLS code. + +2009-01-04 Roland McGrath <roland@redhat.com> + + * note_xlate.h (elf_cvt_note): Don't examine a size too small to + container a note header. + +2008-12-11 Roland McGrath <roland@redhat.com> + + * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle + placement offset going backwards, for out-of-order or overlapping + (bogus) sh_offset layouts. It's a dumb use, but should not crash. + (__elfw2(LIBELFBITS,updatefile)): Likewise. + Fixes RHBZ#476136. + + * libelf.h (Elf_Data): Whitespace fix. + +2008-12-10 Roland McGrath <roland@redhat.com> + + * elf_getarhdr.c (elf_getarhdr): Fix missing rename in last change. + +2008-10-22 Petr Machata <pmachata@redhat.com> + + * elf_rawfile.c (elf_rawfile): Lock around elf-> references. + +2008-10-21 Petr Machata <pmachata@redhat.com> + + * libelfP.h: Rename getehdr_rdlock to getehdr_wrlock. + * elf32_getehdr.c (getehdr_rdlock): Move the code to new function + getehdr_impl and make it a wrapper. Rename to getehdr_wrlock. + (getehdr_impl): Guard elf->class init with wrlock. + (getehdr): Also make it a wrapper of getehdr_impl. + * elf32_updatenull.c (updatenull_wrlock): Call getehdr_wrlock. + +2008-10-20 Petr Machata <pmachata@redhat.com> + + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Lock around the + code that reads mutable elf state. Relock to write lock to chain + the new chunk on the elf rawchunks list. + +2008-10-20 Petr Machata <pmachata@redhat.com> + + * elf32_checksum.c (checksum): Place a lock around the code that + processes data. Make it wrlock if the code needs to xlate the + data before processing. + +2008-10-16 Petr Machata <pmachata@redhat.com> + + * elf_begin.c + (__libelf_next_arhdr): Rename to __libelf_next_arhdr_wrlock. + (dup_elf): Adjust the call. + (elf_begin): New local function lock_dup_elf. Relocks the elf if + necessary before calling dup. Call this instead of dup_elf. + * elf_getarhdr.c + (elf_getarhdr): Lock before calling __libelf_next_arhdr_wrlock. + * elf_next.c (elf_next): Likewise. + * elf_rand.c (elf_rand): Likewise. + +2008-10-14 Petr Machata <pmachata@redhat.com> + + * elf_getdata.c (__elf_getdata_rdlock): Lock before converting. + +2008-11-26 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2008-10-06 Roland McGrath <roland@redhat.com> + + * elf_getarhdr.c (elf_getarhdr): Return NULL when passed NULL. + +2008-08-27 Roland McGrath <roland@redhat.com> + + * elf_begin.c (get_shnum): Avoid misaligned reads for matching endian. + + * libelfP.h [!ALLOW_UNALIGNED] (__libelf_type_align): Fix CLASS index. + +2008-08-25 Roland McGrath <roland@redhat.com> + + * Makefile.am (libelf_so_LDLIBS): New variable. + (libelf.so): Use it in the link. + +2008-08-21 Petr Machata <pmachata@redhat.com> + + * elf_getdata.c, libelfP.h + (__elf_getdata_internal): Rename to __elf_getdata_rdlock. + (__libelf_set_rawdata_wrlock): New function. + (__libelf_set_rawdata): Make it a wrapper that calls *_wrlock. + * elf32_updatenull.c, libelfP.h + (__elfNN_updatenull): Rename to __elfNN_updatenull_wrlock. + +2008-08-21 Petr Machata <pmachata@redhat.com> + + * elf32_getphdr.c, libelfP.h + (__elfNN_getphdr_internal): Drop. Move __elfNN_getphdr_internal + code to __elfNN_getphdr_wrlock. + (__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): New functions. + (__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): Make these + wrappers of getphdr_impl. + +2008-08-21 Petr Machata <pmachata@redhat.com> + + * elf32_getehdr.c, libelfP.h + (__elfNN_getehdr_internal): Rename to __elfNN_getehdr_rdlock. + * gelf_getehdr, libelfP.h: + (__gelf_getehdr_internal): Rename to __gelf_getehdr_rdlock. + +2008-08-21 Petr Machata <pmachata@redhat.com> + + * elf32_getshdr.c + (__elfNN_getshdr_internal): Drop. + (load_shdr_wrlock, scn_valid): New functions, contain bits of + behaviour from __elfNN_getshdr_internal. + (__elfNN_getshdr_rdlock, __elfNN_getshdr_wrlock): Replacements for + dropped _internal functions above. + * elf_getshnum.c + (__elf_getshnum_internal): Rename to __elf_getshnum_rdlock. + +2008-08-04 Petr Machata <pmachata@redhat.com> + + * libelfP.h (RWLOCK_RDLOCK, RWLOCK_WRLOCK, RWLOCK_UNLOCK): New macros. + +2008-07-28 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2008-03-31 Roland McGrath <roland@redhat.com> + + * elf32_offscn.c: Make sure shdrs have been read in. + +2008-02-19 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2008-02-08 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2008-01-31 Ulrich Drepper <drepper@redhat.com> + + * elf_strptr.c (elf_strptr): Don't fail if the ELF file is currently + under construction and no raw data can be read from disk. + +2008-01-30 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2008-01-26 Roland McGrath <roland@redhat.com> + + * elf_begin.c (__libelf_next_arhdr): Rewrite conversions using a macro. + Fixes various pastos in wrong type in sizeof, wrong string parsed. + +2008-01-20 Roland McGrath <roland@redhat.com> + + * elf_getaroff.c: Calculate from start_offset, instead of using + parent's state.ar.offset field. + +2008-01-08 Roland McGrath <roland@redhat.com> + + * Makefile.am (euinclude): Variable removed. + (pkginclude_HEADERS): Set this instead of euinclude_HEADERS. + +2008-01-03 Roland McGrath <roland@redhat.com> + + * common.h: Add __attribute__ ((unused)) to static functions. + +2007-12-20 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (libelf_a_SOURCES): Add elf_scnshndx. + * libelfP.h (struct Elf_Scn): Add shndx_index field. + Declare __elf_scnshndx_internal. + * elf32_getshdr.c: Record location of extended section header. + * elf_begin.c (file_read_elf): Likewise. + * elf_scnshndx.c: New file. + * libelf.h: Declare elf_scnshndx. + * libelf.map: Add elf_scnshndx to version ELFUTILS_1.4. + +2007-11-12 Roland McGrath <roland@redhat.com> + + * libelf.h: Replace off64_t with loff_t throughout. + Only that type name is unconditionally defined by <sys/types.h> + +2007-11-03 Roland McGrath <roland@redhat.com> + + * libelf.h (Elf_Data): Comment fix. + +2007-10-18 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2007-10-07 Roland McGrath <roland@redhat.com> + + * elf_begin.c (__libelf_next_arhdr): Fix fencepost error and wrong + member access in terminating name with no trailing /. Trim trailing + spaces when there is no /. + +2007-10-04 Roland McGrath <roland@redhat.com> + + * elf_end.c (elf_end): Don't free ELF->state.ar.ar_sym when it's -1l. + +2007-10-03 Roland McGrath <roland@redhat.com> + + * libelf.h (Elf_Data): Use off64_t for d_off. + (Elf_Arhdr): Use off64_t for ar_size. + (elf_update, elf_getbase, elf_getaroff): Return off64_t. + + * gelf_rawchunk.c: File removed. + * gelf_freechunk.c: File removed. + * Makefile.am (libelf_a_SOURCES): Remove them. + * libelf.map (ELFUTILS_1.0): Remove exports. + * gelf.h: Remove decls. + + * elf_getdata_rawchunk.c: New file. + * Makefile.am (libelf_a_SOURCES): Add it. + * libelf.map (ELFUTILS_1.3): Add elf_getdata_rawchunk. + * libelf.h: Declare it. + * libelfP.h (Elf_Data_Chunk): New type. + (struct Elf.elf): New member `rawchunks'. + * elf_end.c (elf_end): Free recorded rawchunk buffers. + +2007-08-24 Roland McGrath <roland@redhat.com> + + * gelf_getnote.c: New file. + * Makefile.am (libelf_a_SOURCES): Add it. + * gelf.h: Declare gelf_getnote. + * libelf.map (ELFUTILS_1.3): Add gelf_getnote. + + * libelfP.h (NOTE_ALIGN): New macro. + * note_xlate.h: New file. + * Makefile.am (noinst_HEADERS): Add it. + * gelf_xlate.c: Include it. + (__elf_xfctstom): Use elf_cvt_note. + * elf_getdata.c (shtype_map, __libelf_type_align): Handle SHT_NOTE. + (__libelf_set_rawdata): Likewise. + +2007-08-19 Roland McGrath <roland@redhat.com> + + * gelf_update_auxv.c: New file. + * gelf_getauxv.c: New file. + * Makefile.am (libelf_a_SOURCES): Add them. + * gelf.h: Declare gelf_getauxv, gelf_update_auxv. + * libelf.map (ELFUTILS_1.3): New set, inherits fom ELFUTILS_1.2. + Export gelf_getauxv, gelf_update_auxv. + + * libelf.h (Elf_Type): Add ELF_T_AUXV. + * abstract.h: Add auxv_t entries. + * exttypes.h: Likewise. + * gelf_xlate.h: Likewise. + * gelf_xlate.c (__elf_xfctstom): Add ELF_T_AUXV entries. + * gelf_fsize.c (__libelf_type_sizes): Likewise. + +2007-08-12 Roland McGrath <roland@redhat.com> + + * elf32_updatefile.c (compare_sections): Sort secondarily on sh_size, + and only tertiarily on index. + +2007-07-09 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2007-04-22 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2007-03-18 Roland McGrath <roland@redhat.com> + + * elf_begin.c (get_shnum): Fix test for e_shoff being out of bounds. + Return zero when the section headers do not fit within MAXSIZE. + +2007-03-09 Roland McGrath <roland@redhat.com> + + * libelfP.h (LIBELF_EV_IDX): New macro. + (__libelf_type_align): New macro. + [! ALLOW_UNALIGNED]: Declare __libc_type_aligns array. + * elf_getdata.c (shtype_map): Convert to just Elf_Type[][]. + (convert_data, __libelf_set_rawdata): Use that, __libelf_type_align, + and __libelf_type_sizes, in place of old table. + (__libc_type_aligns): New const variable. + +2007-02-04 Ulrich Drepper <drepper@redhat.com> + + * Makefile (libelf.so): Build with -z relro. + + * elf_begin.c (read_file): When using ELF_C_READ_MMAP use MAP_PRIVATE. + +2007-01-30 Ulrich Drepper <drepper@redhat.com> + + * nlist.c: Close file descriptor before returning. + +2007-01-20 Roland McGrath <roland@redhat.com> + + * gnuhash_xlate.h (elf_cvt_gnuhash): Fix fence-post error so we + convert the final word. + + * elf32_getshdr.c: Don't byteswap shdr fields when EI_DATA matches + MY_ELFDATA on !ALLOW_UNALIGNED machines. + +2007-01-18 Roland McGrath <roland@redhat.com> + + * gelf_rawchunk.c (gelf_rawchunk): Clear RESULT pointer after freeing + it on read error. + +2006-10-13 Roland McGrath <roland@redhat.com> + + * elf32_updatenull.c: Look for and accept phdr also for ET_CORE. + * elf_error.c (msgstr): Change ELF_E_INVALID_PHDR string. + +2006-08-29 Roland McGrath <roland@redhat.com> + + * elf32_getphdr.c: Don't byteswap phdr fields when EI_DATA matches + MY_ELFDATA on !ALLOW_UNALIGNED machines. + Reported by Christian Aichinger <Greek0@gmx.net>. + + * Makefile.am (CLEANFILES): Add libelf.so.$(VERSION). + +2006-08-08 Ulrich Drepper <drepper@redhat.com> + + * elf.h (DT_VALNUM): Update. + (DT_ADDRNUM): Likewise. + +2006-07-12 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c: Adjust for internal_function_def removal. + * elf32_updatenull.c: Likewise. + * elf_begin.c: Likewise. + * elf_getdata.c: Likewise. + +2006-07-11 Ulrich Drepper <drepper@redhat.com> + + * libelf.h: Define ELF_T_GNUHASH. + * elf_getdata.c (TYPEIDX): Handle SHT_GNU_HASH. + (shtype_map): Add SHT_GNU_HASH entries. + * gelf_xlate.c (__elf_xfctstom): Add ELF_T_GNUHASH entries. + * gnuhash_xlate.h: New file. + * Makefile.am (noinst_HEADERS): Add gnuhash_xlate.h. + +2006-07-06 Ulrich Drepper <drepper@redhat.com> + + * elf_gnu_hash.c: New file. + * libelf.h: Declare elf_gnu_hash. + * Makefile.am (libelf_a_SOURCES): Add elf_gnu_hash. + * libelf.map: Add elf_gnu_map for version ELFUTILS_1.2. + +2006-06-15 Roland McGrath <roland@redhat.com> + + * libelf.h (elf_getarsym): Fix comment typo. + Rename second parameter to be more explanatory. + (elf_getident, elf_rawhide): Likewise. + +2006-05-28 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c (updatemmap): Preserve section content if + copying would overwrite them. + Fix msync paramters. + +2006-04-04 Roland McGrath <roland@redhat.com> + + * elf32_updatefile.c (updatemmap): Handle other-endian case. + +2006-04-04 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c (updatemmap): Cleanups. Remove shdr_dest + variable. Before writing sections, make a copy of the section + header data if necessary. Don't write section header while + writing the section constent, it might overwrite some sections. + Restore the pointer afterwards. + * elf32_updatenull.c (updatenull): If the offset of a section in a + file changed make sure we read the section so that it'll be written + out. + + * elf_update.c: Remove debug message. + +2005-12-07 Roland McGrath <roland@redhat.com> + + * gelf_xlate.c [! ALLOW_UNALIGNED] (union unaligned): New type. + (FETCH, STORE): New macros. + (INLINE3): Use those to do alignment-friendly conversion. + + * elf32_getshdr.c: Include map_address and start_offset in alignment + calculations. + * elf32_getphdr.c: Likewise. + +2005-11-19 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2005-11-17 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2005-11-10 Roland McGrath <roland@redhat.com> + + * elf.h: Update from glibc. + +2005-09-09 Roland McGrath <roland@redhat.com> + + * elf_update.c (write_file): Stat the file and fchmod it after update + if its mode had S_ISUID or S_ISGID bits set. + +2005-08-28 Ulrich Drepper <drepper@redhat.com> + + * elf32_getphdr.c: Include <system.h>. Use pread_retry instead of + pread. And branch prediction where useful. + * elf_begin.c: Likewise. + * elf_getdata.c: Likewise. + * elf_getshstrndx.c: Likewise. + * elf_readall.c: Likewise. + * gelf_rawchunk.c: Likewise. + * elf32_updatefile.c: Include <system.h>. Use pread_retry instead of + pread. And branch prediction where useful. + * elf_getarsym.c: Don't define pread_retry here. + + * Makefile.am: Use $(LINK) not $(CC) when creating DSO. + (%.os): Use COMPILE.os. + (COMPILE.os): Filter out gconv options. + +2005-08-27 Ulrich Drepper <drepper@redhat.com> + + * elf_begin.c (file_read_elf): Avoid reading ELF header from file + again. Instead accept additional parameter which points to it if we + don't use mmap. + (get_shnum): Use passed in e_ident value as source of ELF header. + +2005-08-15 Ulrich Drepper <drepper@redhat.com> + + * elf_begin.c (__libelf_next_arhdr): Use TEMP_FAILURE_RETRY. + + * Makefile (libelf_a_SOURCES): Add elf_getaroff.c. + * libelf.map: Export elf_getaroff. + * libelf.h: Declare elf_getaroff. + * elf_getaroff.c: New file. + +2005-08-13 Ulrich Drepper <drepper@redhat.com> + + * elf_begin.c (get_shnum): Optimize memory handling. Always read from + mapped file if available. Fix access to 64-bit sh_size. Recognize + overflow. + (file_read_elf): Likewise. + +2005-08-12 Roland McGrath <roland@redhat.com> + + * elf32_offscn.c: Do not match empty sections at OFFSET unless + there are no nonempty sections at that offset. + +2005-08-07 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update from glibc. + +2005-08-06 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (AM_CFLAGS): Add -fpic when BUILD_STATIC. + +2005-08-03 Ulrich Drepper <drepper@redhat.com> + + * libelf.map: Move elf32_offscn, elf64_offscn, and gelf_offscn in + new version ELFUTILS_1.1.1. + +2005-08-02 Ulrich Drepper <drepper@redhat.com> + + * elf_error.c: Add handling of ELF_E_INVALID_OFFSET. + * elf32_offscn.c: New file. + * elf64_offscn.c: New file. + * gelf_offscn.c: New file. + * Makefile.am (libelf_a_SOURCES): Add elf32_offscn.c, elf64_offscn.c, + and gelf_offscn.c. + * libelf.sym: Export new symbols. + +2005-07-23 Ulrich Drepper <drepper@redhat.com> + + * elf-knowledge.h (SECTION_STRIP_P): Don't handle removal of debug + sections here anymore. + * elf32_checksum.c: Adjust for change in SECTION_STRIP_P interface. + + * elf_update.c (elf_update): Get write lock, not read lock. + + * elf32_updatenull.c (updatenull): Get section headers if necessary + and possible. + +2005-07-22 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatenull.c (updatenull): If program header hasn't been loaded + yet, try to do it now. + Don't unnecessarily update overflow of section count in zeroth section + sh_size field. + If section content hasn't been read yet, do it before looking for the + block size. If no section data present, infer size of section header. + +2005-05-11 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update again. + +2005-05-09 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update from glibc. + +2005-05-08 Roland McGrath <roland@redhat.com> + + * elf_begin.c (read_file) [_MUDFLAP]: Don't use mmap for now. + * elf_update.c (write_file) [_MUDFLAP]: Likewise. + +2005-03-29 Ulrich Drepper <drepper@redhat.com> + + * elf32_checksum.c: Use INTUSE and INTDEF to avoid PLTs. + * elf_end.c: Likewise. + * elf_getdata.c: Likewise. + * gelf_getehdr.c: Likewise. + * nlist.c: Likewise. + * libelfP.h: Add declarations of internal functions. + +2005-02-15 Ulrich Drepper <drepper@redhat.com> + + * common.h (CONVERT): Make sure all values are unsigned. + (CONVERT_TO): Likewise. + + * Makefile.am (AM_CFLAGS): Add -Wformat=2. + Fix rule to build libelf.so. + +2005-02-06 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Cleanup AM_CFLAGS handling. Add -Wunused -Wextra. + Remove lint handling. + * elf32_getphdr.c: Minor cleanups. + * elf32_getshdr.c: Likewise. + * elf32_updatefile.c: Likewise. + * elf32_updatenull.c: Likewise. + * elf_begin.c: Likewise. + * elf_error.c: Likewise. + * elf_getarsym.c: Likewise. + * elf_getdata.c: Likewise. + * elf_update.c: Likewise. + * gelf_xlate.c: Likewise. + +2005-02-05 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Check for text relocations in constructed DSO. + + * Makefile.am [MUDFLAP] (AM_CFLAGS): Add -Werror -fpic -fmudflap. + +2005-02-04 Ulrich Drepper <drepper@redhat.com> + + * gelf_getehdr.c (gelf_getehdr): Slight optimization. + + * elf32_checksum.c (checksum): Do not look at NOBITS sections. + + * gelf.h: Add gelf_checksum prototype. + +2004-09-25 Ulrich Drepper <drepper@redhat.com> + + * elf32_checksum.c: Make compile with gcc 4.0. + * elf32_updatefile.c: Likewise. + * elf32_updatenull.c: Likewise. + * elf_begin.c: Likewise. + * elf_error.c: Likewise. + * elf_getdata.c: Likewise. + * elf_getident.c: Likewise. + +2004-04-01 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Update from glibc. + +2004-01-23 Ulrich Drepper <drepper@redhat.com> + + * elf_update.c: Fix locking. + * elf_clone.c: Likewise. + + * libelf.h: Define ELF_T_LIB. + * gelf_getlib.c: New file. + * gelf_update_lib.c: New file. + * gelf.h: Declare the new functions. Define GElf_Lib. + * abstract.h: Define Lib, Lib32, Lib64. + * gelf_xlate.c (__elf_xfctstom): Add ELF_T_LIB entry. + * gelf_xlate.h: Add entry for ElfXX_Lib. + * elf_getdata.c: Recognize SHT_GNU_LIBLIST as a known section type. + * libelf.map: Add new symbols to ELFUTILS_1.1. + * Makefile.am (libelf_a_SOURCES): Add gelf_getlib.c and + gelf_update_lib.c. + +2004-01-17 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Support building with mudflap. + + * gelf_xlate.c (INLINE3): Avoid using cast as lvalue. + * dl-hash.h (_dl_elf_hash): Likewise. + +2004-01-05 Ulrich Drepper <drepper@redhat.com> + + * elf-knowledge.h: New file. From libelf subdir. + * Makefile.am (euincludedir): Define. + (euinclude_HEADERS): Add elf-knowledge.h. + +2003-09-24 Ulrich Drepper <drepper@redhat.com> + + * elf.h: Define some PT_IA_64_HP_* constants. + +2003-09-23 Jakub Jelinek <jakub@redhat.com> + + * libelfP.h (struct Elf): Move state.elf64.sizestr_offset after + state.elf64.scnincr to match state.elf{,32}. + +2003-08-12 Ulrich Drepper <drepper@redhat.com> + + * elf32_updatefile.c (__updatemmap): When writing back file where + some sections have not been read in, count their sizes based on + the section header. + +2003-08-11 Ulrich Drepper <drepper@redhat.com> + + * Moved to CVS archive. diff --git a/libelf/Makefile.am b/libelf/Makefile.am new file mode 100644 index 0000000..c7c83f3 --- /dev/null +++ b/libelf/Makefile.am @@ -0,0 +1,125 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 1996-2010 Red Hat, Inc. +## This file is part of Red Hat elfutils. +## +## Red Hat elfutils is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by the +## Free Software Foundation; version 2 of the License. +## +## Red Hat elfutils is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with Red Hat elfutils; if not, write to the Free Software Foundation, +## Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +## +## Red Hat elfutils is an included package of the Open Invention Network. +## An included package of the Open Invention Network is a package for which +## Open Invention Network licensees cross-license their patents. No patent +## license is granted, either expressly or impliedly, by designation as an +## included package. Should you wish to participate in the Open Invention +## Network licensing program, please visit www.openinventionnetwork.com +## <http://www.openinventionnetwork.com>. +## +include $(top_srcdir)/config/eu.am +if BUILD_STATIC +AM_CFLAGS += -fpic +endif +GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include) +VERSION = 1 + +lib_LIBRARIES = libelf.a +if !MUDFLAP +noinst_LIBRARIES = libelf_pic.a +noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so) +endif +include_HEADERS = libelf.h gelf.h nlist.h + +pkginclude_HEADERS = elf-knowledge.h + +libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \ + elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \ + gelf_getclass.c elf_getbase.c elf_getident.c \ + elf32_fsize.c elf64_fsize.c gelf_fsize.c \ + elf32_xlatetof.c elf32_xlatetom.c elf64_xlatetof.c \ + elf64_xlatetom.c gelf_xlate.c \ + elf32_getehdr.c elf64_getehdr.c gelf_getehdr.c \ + elf32_newehdr.c elf64_newehdr.c gelf_newehdr.c \ + gelf_update_ehdr.c \ + elf32_getphdr.c elf64_getphdr.c gelf_getphdr.c \ + elf32_newphdr.c elf64_newphdr.c gelf_newphdr.c \ + gelf_update_phdr.c \ + elf_getarhdr.c elf_getarsym.c \ + elf_rawfile.c elf_readall.c elf_cntl.c \ + elf_getscn.c elf_nextscn.c elf_ndxscn.c elf_newscn.c \ + elf32_getshdr.c elf64_getshdr.c gelf_getshdr.c \ + gelf_update_shdr.c \ + elf_strptr.c elf_rawdata.c elf_getdata.c elf_newdata.c \ + elf_getdata_rawchunk.c \ + elf_flagelf.c elf_flagehdr.c elf_flagphdr.c elf_flagscn.c \ + elf_flagshdr.c elf_flagdata.c elf_memory.c \ + elf_update.c elf32_updatenull.c elf64_updatenull.c \ + elf32_updatefile.c elf64_updatefile.c \ + gelf_getsym.c gelf_update_sym.c \ + gelf_getversym.c gelf_getverneed.c gelf_getvernaux.c \ + gelf_getverdef.c gelf_getverdaux.c \ + gelf_getrel.c gelf_getrela.c \ + gelf_update_rel.c gelf_update_rela.c \ + gelf_getdyn.c gelf_update_dyn.c \ + gelf_getmove.c gelf_update_move.c \ + gelf_getsyminfo.c gelf_update_syminfo.c \ + gelf_getauxv.c gelf_update_auxv.c \ + gelf_getnote.c \ + gelf_xlatetof.c gelf_xlatetom.c \ + nlist.c \ + gelf_getsymshndx.c gelf_update_symshndx.c \ + gelf_update_versym.c gelf_update_verneed.c \ + gelf_update_vernaux.c gelf_update_verdef.c \ + gelf_update_verdaux.c \ + elf_getphdrnum.c elf_getshdrnum.c elf_getshdrstrndx.c \ + gelf_checksum.c elf32_checksum.c elf64_checksum.c \ + libelf_crc32.c libelf_next_prime.c \ + elf_clone.c \ + gelf_getlib.c gelf_update_lib.c \ + elf32_offscn.c elf64_offscn.c gelf_offscn.c \ + elf_getaroff.c \ + elf_gnu_hash.c \ + elf_scnshndx.c + +if !MUDFLAP +libelf_pic_a_SOURCES = +am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os) + +libelf_so_LDLIBS = +if USE_LOCKS +libelf_so_LDLIBS += -lpthread +endif + +libelf_so_SOURCES = +libelf.so: libelf_pic.a libelf.map + $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libelf.map,--no-undefined \ + -Wl,--soname,$@.$(VERSION),-z,defs,-z,relro $(libelf_so_LDLIBS) + if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi + ln -fs $@ $@.$(VERSION) + +install: install-am libelf.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so + ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION) + ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libelf.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libelf.so +endif + +noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \ + version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h +EXTRA_DIST = libelf.map + +CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so.$(VERSION) diff --git a/libelf/Makefile.in b/libelf/Makefile.in new file mode 100644 index 0000000..fcb3ed5 --- /dev/null +++ b/libelf/Makefile.in @@ -0,0 +1,843 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(include_HEADERS) $(noinst_HEADERS) \ + $(pkginclude_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/config/eu.am ChangeLog +@MUDFLAP_TRUE@am__append_1 = -fmudflap +@BUILD_STATIC_TRUE@am__append_2 = -fpic +@MUDFLAP_FALSE@noinst_PROGRAMS = $(am__EXEEXT_1) +@MUDFLAP_TRUE@am_libelf_pic_a_OBJECTS = +@MUDFLAP_FALSE@@USE_LOCKS_TRUE@am__append_3 = -lpthread +subdir = libelf +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(pkgincludedir)" +LIBRARIES = $(lib_LIBRARIES) $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libelf_a_AR = $(AR) $(ARFLAGS) +libelf_a_LIBADD = +am_libelf_a_OBJECTS = elf_version.$(OBJEXT) elf_hash.$(OBJEXT) \ + elf_error.$(OBJEXT) elf_fill.$(OBJEXT) elf_begin.$(OBJEXT) \ + elf_next.$(OBJEXT) elf_rand.$(OBJEXT) elf_end.$(OBJEXT) \ + elf_kind.$(OBJEXT) gelf_getclass.$(OBJEXT) \ + elf_getbase.$(OBJEXT) elf_getident.$(OBJEXT) \ + elf32_fsize.$(OBJEXT) elf64_fsize.$(OBJEXT) \ + gelf_fsize.$(OBJEXT) elf32_xlatetof.$(OBJEXT) \ + elf32_xlatetom.$(OBJEXT) elf64_xlatetof.$(OBJEXT) \ + elf64_xlatetom.$(OBJEXT) gelf_xlate.$(OBJEXT) \ + elf32_getehdr.$(OBJEXT) elf64_getehdr.$(OBJEXT) \ + gelf_getehdr.$(OBJEXT) elf32_newehdr.$(OBJEXT) \ + elf64_newehdr.$(OBJEXT) gelf_newehdr.$(OBJEXT) \ + gelf_update_ehdr.$(OBJEXT) elf32_getphdr.$(OBJEXT) \ + elf64_getphdr.$(OBJEXT) gelf_getphdr.$(OBJEXT) \ + elf32_newphdr.$(OBJEXT) elf64_newphdr.$(OBJEXT) \ + gelf_newphdr.$(OBJEXT) gelf_update_phdr.$(OBJEXT) \ + elf_getarhdr.$(OBJEXT) elf_getarsym.$(OBJEXT) \ + elf_rawfile.$(OBJEXT) elf_readall.$(OBJEXT) elf_cntl.$(OBJEXT) \ + elf_getscn.$(OBJEXT) elf_nextscn.$(OBJEXT) \ + elf_ndxscn.$(OBJEXT) elf_newscn.$(OBJEXT) \ + elf32_getshdr.$(OBJEXT) elf64_getshdr.$(OBJEXT) \ + gelf_getshdr.$(OBJEXT) gelf_update_shdr.$(OBJEXT) \ + elf_strptr.$(OBJEXT) elf_rawdata.$(OBJEXT) \ + elf_getdata.$(OBJEXT) elf_newdata.$(OBJEXT) \ + elf_getdata_rawchunk.$(OBJEXT) elf_flagelf.$(OBJEXT) \ + elf_flagehdr.$(OBJEXT) elf_flagphdr.$(OBJEXT) \ + elf_flagscn.$(OBJEXT) elf_flagshdr.$(OBJEXT) \ + elf_flagdata.$(OBJEXT) elf_memory.$(OBJEXT) \ + elf_update.$(OBJEXT) elf32_updatenull.$(OBJEXT) \ + elf64_updatenull.$(OBJEXT) elf32_updatefile.$(OBJEXT) \ + elf64_updatefile.$(OBJEXT) gelf_getsym.$(OBJEXT) \ + gelf_update_sym.$(OBJEXT) gelf_getversym.$(OBJEXT) \ + gelf_getverneed.$(OBJEXT) gelf_getvernaux.$(OBJEXT) \ + gelf_getverdef.$(OBJEXT) gelf_getverdaux.$(OBJEXT) \ + gelf_getrel.$(OBJEXT) gelf_getrela.$(OBJEXT) \ + gelf_update_rel.$(OBJEXT) gelf_update_rela.$(OBJEXT) \ + gelf_getdyn.$(OBJEXT) gelf_update_dyn.$(OBJEXT) \ + gelf_getmove.$(OBJEXT) gelf_update_move.$(OBJEXT) \ + gelf_getsyminfo.$(OBJEXT) gelf_update_syminfo.$(OBJEXT) \ + gelf_getauxv.$(OBJEXT) gelf_update_auxv.$(OBJEXT) \ + gelf_getnote.$(OBJEXT) gelf_xlatetof.$(OBJEXT) \ + gelf_xlatetom.$(OBJEXT) nlist.$(OBJEXT) \ + gelf_getsymshndx.$(OBJEXT) gelf_update_symshndx.$(OBJEXT) \ + gelf_update_versym.$(OBJEXT) gelf_update_verneed.$(OBJEXT) \ + gelf_update_vernaux.$(OBJEXT) gelf_update_verdef.$(OBJEXT) \ + gelf_update_verdaux.$(OBJEXT) elf_getphdrnum.$(OBJEXT) \ + elf_getshdrnum.$(OBJEXT) elf_getshdrstrndx.$(OBJEXT) \ + gelf_checksum.$(OBJEXT) elf32_checksum.$(OBJEXT) \ + elf64_checksum.$(OBJEXT) libelf_crc32.$(OBJEXT) \ + libelf_next_prime.$(OBJEXT) elf_clone.$(OBJEXT) \ + gelf_getlib.$(OBJEXT) gelf_update_lib.$(OBJEXT) \ + elf32_offscn.$(OBJEXT) elf64_offscn.$(OBJEXT) \ + gelf_offscn.$(OBJEXT) elf_getaroff.$(OBJEXT) \ + elf_gnu_hash.$(OBJEXT) elf_scnshndx.$(OBJEXT) +libelf_a_OBJECTS = $(am_libelf_a_OBJECTS) +libelf_pic_a_AR = $(AR) $(ARFLAGS) +libelf_pic_a_LIBADD = +libelf_pic_a_OBJECTS = $(am_libelf_pic_a_OBJECTS) +@MUDFLAP_FALSE@am__EXEEXT_1 = libelf.so$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am_libelf_so_OBJECTS = +libelf_so_OBJECTS = $(am_libelf_so_OBJECTS) +libelf_so_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libelf_a_SOURCES) $(libelf_pic_a_SOURCES) \ + $(libelf_so_SOURCES) +DIST_SOURCES = $(libelf_a_SOURCES) $(libelf_pic_a_SOURCES) \ + $(libelf_so_SOURCES) +HEADERS = $(include_HEADERS) $(noinst_HEADERS) $(pkginclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBEBL_SUBDIR = @LIBEBL_SUBDIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MODVERSION = @MODVERSION@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +base_cpu = @base_cpu@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +INCLUDES = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. +AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \ + $($(*F)_no_Werror),,-Werror) $(if \ + $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \ + $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \ + $(am__append_1) $(am__append_2) +@MUDFLAP_FALSE@libmudflap = +@MUDFLAP_TRUE@libmudflap = -lmudflap +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage $(no_mudflap.os),\ + $(COMPILE)) + +CLEANFILES = *.gcno *.gcda $(am_libelf_pic_a_OBJECTS) \ + libelf.so.$(VERSION) +textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi +GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include) +lib_LIBRARIES = libelf.a +@MUDFLAP_FALSE@noinst_LIBRARIES = libelf_pic.a +include_HEADERS = libelf.h gelf.h nlist.h +pkginclude_HEADERS = elf-knowledge.h +libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \ + elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \ + gelf_getclass.c elf_getbase.c elf_getident.c \ + elf32_fsize.c elf64_fsize.c gelf_fsize.c \ + elf32_xlatetof.c elf32_xlatetom.c elf64_xlatetof.c \ + elf64_xlatetom.c gelf_xlate.c \ + elf32_getehdr.c elf64_getehdr.c gelf_getehdr.c \ + elf32_newehdr.c elf64_newehdr.c gelf_newehdr.c \ + gelf_update_ehdr.c \ + elf32_getphdr.c elf64_getphdr.c gelf_getphdr.c \ + elf32_newphdr.c elf64_newphdr.c gelf_newphdr.c \ + gelf_update_phdr.c \ + elf_getarhdr.c elf_getarsym.c \ + elf_rawfile.c elf_readall.c elf_cntl.c \ + elf_getscn.c elf_nextscn.c elf_ndxscn.c elf_newscn.c \ + elf32_getshdr.c elf64_getshdr.c gelf_getshdr.c \ + gelf_update_shdr.c \ + elf_strptr.c elf_rawdata.c elf_getdata.c elf_newdata.c \ + elf_getdata_rawchunk.c \ + elf_flagelf.c elf_flagehdr.c elf_flagphdr.c elf_flagscn.c \ + elf_flagshdr.c elf_flagdata.c elf_memory.c \ + elf_update.c elf32_updatenull.c elf64_updatenull.c \ + elf32_updatefile.c elf64_updatefile.c \ + gelf_getsym.c gelf_update_sym.c \ + gelf_getversym.c gelf_getverneed.c gelf_getvernaux.c \ + gelf_getverdef.c gelf_getverdaux.c \ + gelf_getrel.c gelf_getrela.c \ + gelf_update_rel.c gelf_update_rela.c \ + gelf_getdyn.c gelf_update_dyn.c \ + gelf_getmove.c gelf_update_move.c \ + gelf_getsyminfo.c gelf_update_syminfo.c \ + gelf_getauxv.c gelf_update_auxv.c \ + gelf_getnote.c \ + gelf_xlatetof.c gelf_xlatetom.c \ + nlist.c \ + gelf_getsymshndx.c gelf_update_symshndx.c \ + gelf_update_versym.c gelf_update_verneed.c \ + gelf_update_vernaux.c gelf_update_verdef.c \ + gelf_update_verdaux.c \ + elf_getphdrnum.c elf_getshdrnum.c elf_getshdrstrndx.c \ + gelf_checksum.c elf32_checksum.c elf64_checksum.c \ + libelf_crc32.c libelf_next_prime.c \ + elf_clone.c \ + gelf_getlib.c gelf_update_lib.c \ + elf32_offscn.c elf64_offscn.c gelf_offscn.c \ + elf_getaroff.c \ + elf_gnu_hash.c \ + elf_scnshndx.c + +@MUDFLAP_FALSE@libelf_pic_a_SOURCES = +@MUDFLAP_FALSE@am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os) +@MUDFLAP_FALSE@libelf_so_LDLIBS = $(am__append_3) +@MUDFLAP_FALSE@libelf_so_SOURCES = +noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \ + version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h + +EXTRA_DIST = libelf.map +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libelf/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits libelf/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libdir)' && rm -f "$$files" )"; \ + cd "$(DESTDIR)$(libdir)" && rm -f $$files + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libelf.a: $(libelf_a_OBJECTS) $(libelf_a_DEPENDENCIES) + -rm -f libelf.a + $(libelf_a_AR) libelf.a $(libelf_a_OBJECTS) $(libelf_a_LIBADD) + $(RANLIB) libelf.a +libelf_pic.a: $(libelf_pic_a_OBJECTS) $(libelf_pic_a_DEPENDENCIES) + -rm -f libelf_pic.a + $(libelf_pic_a_AR) libelf_pic.a $(libelf_pic_a_OBJECTS) $(libelf_pic_a_LIBADD) + $(RANLIB) libelf_pic.a + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +@MUDFLAP_TRUE@libelf.so$(EXEEXT): $(libelf_so_OBJECTS) $(libelf_so_DEPENDENCIES) +@MUDFLAP_TRUE@ @rm -f libelf.so$(EXEEXT) +@MUDFLAP_TRUE@ $(LINK) $(libelf_so_OBJECTS) $(libelf_so_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_checksum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_fsize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getphdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getshdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_newehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_newphdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_offscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_updatefile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_updatenull.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_xlatetof.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_xlatetom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_checksum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_fsize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getphdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getshdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_newehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_newphdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_offscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_updatefile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_updatenull.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_xlatetof.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_xlatetom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_begin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_clone.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_cntl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_end.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_fill.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagdata.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagelf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagphdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagshdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getarhdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getaroff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getarsym.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getbase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getdata.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getdata_rawchunk.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getident.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getphdrnum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getshdrnum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getshdrstrndx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_gnu_hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_kind.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_memory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_ndxscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_newdata.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_newscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_next.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_nextscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_rand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_rawdata.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_rawfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_readall.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_scnshndx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_strptr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_update.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_version.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_checksum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_fsize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getauxv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getclass.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getdyn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getlib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getmove.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getnote.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getphdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getrel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getrela.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getshdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getsym.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getsyminfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getsymshndx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getverdaux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getverdef.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getvernaux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getverneed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getversym.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_newehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_newphdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_offscn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_auxv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_dyn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_ehdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_lib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_move.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_phdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_rel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_rela.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_shdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_sym.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_syminfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_symshndx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_verdaux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_verdef.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_vernaux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_verneed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_versym.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_xlate.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_xlatetof.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_xlatetom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libelf_crc32.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libelf_next_prime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlist.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(includedir)" && rm -f $$files +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files + +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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +@MUDFLAP_TRUE@install: install-am +install-exec: install-exec-am +install-data: install-data-am +@MUDFLAP_TRUE@uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-libLIBRARIES clean-noinstLIBRARIES \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLIBRARIES \ + uninstall-pkgincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLIBRARIES clean-noinstLIBRARIES clean-noinstPROGRAMS \ + ctags distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLIBRARIES install-man install-pdf \ + install-pdf-am install-pkgincludeHEADERS install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLIBRARIES uninstall-pkgincludeHEADERS + + +%.os: %.c %.o +@AMDEP_TRUE@ if $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED $< +@MUDFLAP_FALSE@libelf.so: libelf_pic.a libelf.map +@MUDFLAP_FALSE@ $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ +@MUDFLAP_FALSE@ -Wl,--version-script,$(srcdir)/libelf.map,--no-undefined \ +@MUDFLAP_FALSE@ -Wl,--soname,$@.$(VERSION),-z,defs,-z,relro $(libelf_so_LDLIBS) +@MUDFLAP_FALSE@ if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi +@MUDFLAP_FALSE@ ln -fs $@ $@.$(VERSION) + +@MUDFLAP_FALSE@install: install-am libelf.so +@MUDFLAP_FALSE@ $(mkinstalldirs) $(DESTDIR)$(libdir) +@MUDFLAP_FALSE@ $(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so +@MUDFLAP_FALSE@ ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION) +@MUDFLAP_FALSE@ ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so + +@MUDFLAP_FALSE@uninstall: uninstall-am +@MUDFLAP_FALSE@ rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so +@MUDFLAP_FALSE@ rm -f $(DESTDIR)$(libdir)/libelf.so.$(VERSION) +@MUDFLAP_FALSE@ rm -f $(DESTDIR)$(libdir)/libelf.so + +# 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/libelf/abstract.h b/libelf/abstract.h new file mode 100644 index 0000000..e359f96 --- /dev/null +++ b/libelf/abstract.h @@ -0,0 +1,333 @@ +/* Abstract description of component ELF types. + Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +/* ELF header. */ +#define Ehdr(Bits, Ext) \ +START (Bits, Ehdr, Ext##Ehdr) \ + TYPE_EXTRA (unsigned char e_ident[EI_NIDENT];) \ + TYPE_XLATE (memmove (tdest->e_ident, tsrc->e_ident, EI_NIDENT);) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_type) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_machine) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), e_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Addr), e_entry) \ + TYPE_NAME (ElfW2(Bits, Ext##Off), e_phoff) \ + TYPE_NAME (ElfW2(Bits, Ext##Off), e_shoff) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), e_flags) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_ehsize) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_phentsize) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_phnum) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_shentsize) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_shnum) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_shstrndx) \ +END (Bits, Ext##Ehdr) + +#define Ehdr32(Ext) \ + Ehdr(32, Ext) +#define Ehdr64(Ext) \ + Ehdr(64, Ext) + + +/* Program header. */ +#define Phdr32(Ext) \ +START (32, Phdr, Ext##Phdr) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_type) \ + TYPE_NAME (ElfW2(32, Ext##Off), p_offset) \ + TYPE_NAME (ElfW2(32, Ext##Addr), p_vaddr) \ + TYPE_NAME (ElfW2(32, Ext##Addr), p_paddr) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_filesz) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_memsz) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_flags) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_align) \ +END (32, Ext##Phdr) +#define Phdr64(Ext) \ +START (64, Phdr, Ext##Phdr) \ + TYPE_NAME (ElfW2(64, Ext##Word), p_type) \ + TYPE_NAME (ElfW2(64, Ext##Word), p_flags) \ + TYPE_NAME (ElfW2(64, Ext##Off), p_offset) \ + TYPE_NAME (ElfW2(64, Ext##Addr), p_vaddr) \ + TYPE_NAME (ElfW2(64, Ext##Addr), p_paddr) \ + TYPE_NAME (ElfW2(64, Ext##Xword), p_filesz) \ + TYPE_NAME (ElfW2(64, Ext##Xword), p_memsz) \ + TYPE_NAME (ElfW2(64, Ext##Xword), p_align) \ +END (64, Ext##Phdr) + + +/* Section header. */ +#define Shdr32(Ext) \ +START (32, Shdr, Ext##Shdr) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_name) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_type) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_flags) \ + TYPE_NAME (ElfW2(32, Ext##Addr), sh_addr) \ + TYPE_NAME (ElfW2(32, Ext##Off), sh_offset) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_size) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_link) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_info) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_addralign) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_entsize) \ +END (32, Ext##Shdr) +#define Shdr64(Ext) \ +START (64, Shdr, Ext##Shdr) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_name) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_type) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_flags) \ + TYPE_NAME (ElfW2(64, Ext##Addr), sh_addr) \ + TYPE_NAME (ElfW2(64, Ext##Off), sh_offset) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_size) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_link) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_info) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_addralign) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_entsize) \ +END (64, Ext##Shdr) + + +/* Symbol table. */ +#define Sym32(Ext) \ +START (32, Sym, Ext##Sym) \ + TYPE_NAME (ElfW2(32, Ext##Word), st_name) \ + TYPE_NAME (ElfW2(32, Ext##Addr), st_value) \ + TYPE_NAME (ElfW2(32, Ext##Word), st_size) \ + TYPE_EXTRA (unsigned char st_info;) \ + TYPE_XLATE (tdest->st_info = tsrc->st_info;) \ + TYPE_EXTRA (unsigned char st_other;) \ + TYPE_XLATE (tdest->st_other = tsrc->st_other;) \ + TYPE_NAME (ElfW2(32, Ext##Half), st_shndx) \ +END (32, Ext##Sym) +#define Sym64(Ext) \ +START (64, Sym, Ext##Sym) \ + TYPE_NAME (ElfW2(64, Ext##Word), st_name) \ + TYPE_EXTRA (unsigned char st_info;) \ + TYPE_XLATE (tdest->st_info = tsrc->st_info;) \ + TYPE_EXTRA (unsigned char st_other;) \ + TYPE_XLATE (tdest->st_other = tsrc->st_other;) \ + TYPE_NAME (ElfW2(64, Ext##Half), st_shndx) \ + TYPE_NAME (ElfW2(64, Ext##Addr), st_value) \ + TYPE_NAME (ElfW2(64, Ext##Xword), st_size) \ +END (64, Ext##Sym) + + +/* Relocation. */ +#define Rel32(Ext) \ +START (32, Rel, Ext##Rel) \ + TYPE_NAME (ElfW2(32, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(32, Ext##Word), r_info) \ +END (32, Ext##Rel) +#define Rel64(Ext) \ +START (64, Rel, Ext##Rel) \ + TYPE_NAME (ElfW2(64, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(64, Ext##Xword), r_info) \ +END (64, Ext##Rel) + +#define Rela32(Ext) \ +START (32, Rela, Ext##Rela) \ + TYPE_NAME (ElfW2(32, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(32, Ext##Word), r_info) \ + TYPE_NAME (ElfW2(32, Ext##Sword), r_addend) \ +END (32, Ext##Rela) +#define Rela64(Ext) \ +START (64, Rela, Ext##Rela) \ + TYPE_NAME (ElfW2(64, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(64, Ext##Xword), r_info) \ + TYPE_NAME (ElfW2(64, Ext##Sxword), r_addend) \ +END (64, Ext##Rela) + + +/* Note entry header. */ +#define Note(Bits, Ext) \ +START (Bits, Nhdr, Ext##Nhdr) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), n_namesz) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), n_descsz) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), n_type) \ +END (Bits, Ext##Nhdr) + +#define Note32(Ext) \ + Note (32, Ext) +#define Note64(Ext) \ + Note (64, Ext) + + +/* Dynamic section data. */ +#define Dyn32(Ext) \ +START (32, Dyn, Ext##Dyn) \ + TYPE_NAME (ElfW2(32, Ext##Sword), d_tag) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(32, Ext##Word) d_val;) \ + TYPE_EXTRA (ElfW2(32, Ext##Addr) d_ptr;) \ + TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);) \ + TYPE_EXTRA (ElfW2(32, Ext##Off) d_off;) \ + TYPE_EXTRA (} d_un;) \ +END (32, Ext##Dyn) +#define Dyn64(Ext) \ +START (64, Dyn, Ext##Dyn) \ + TYPE_NAME (ElfW2(64, Ext##Xword), d_tag) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(64, Ext##Xword) d_val;) \ + TYPE_EXTRA (ElfW2(64, Ext##Addr) d_ptr;) \ + TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);) \ + TYPE_EXTRA (} d_un;) \ +END (64, Ext##Dyn) + + +#ifndef GENERATE_CONVERSION +/* Version definitions. */ +# define Verdef(Bits, Ext) \ +START (Bits, Verdef, Ext##Verdef) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_flags) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_ndx) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_cnt) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vd_hash) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vd_aux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vd_next) \ +END (Bits, Ext##Verdef) + +# define Verdef32(Ext) \ + Verdef (32, Ext) +# define Verdef64(Ext) \ + Verdef (64, Ext) + +# define Verdaux(Bits, Ext) \ +START (Bits, Verdaux, Ext##Verdaux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vda_name) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vda_next) \ +END (Bits, Ext##Verdaux) + +# define Verdaux32(Ext) \ + Verdaux (32, Ext) +# define Verdaux64(Ext) \ + Verdaux (64, Ext) + +/* Required versions. */ +# define Verneed(Bits, Ext) \ +START (Bits, Verneed, Ext##Verneed) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vn_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vn_cnt) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vn_file) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vn_aux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vn_next) \ +END (Bits, Ext##Verneed) + +# define Verneed32(Ext) \ + Verneed (32, Ext) +# define Verneed64(Ext) \ + Verneed (64, Ext) + +# define Vernaux(Bits, Ext) \ +START (Bits, Vernaux, Ext##Vernaux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vna_hash) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vna_flags) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vna_other) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vna_name) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vna_next) \ +END (Bits, Ext##Vernaux) + +# define Vernaux32(Ext) \ + Vernaux (32, Ext) +# define Vernaux64(Ext) \ + Vernaux (64, Ext) +#endif + +/* Symbol information. */ +#define Syminfo(Bits, Ext) \ +START (Bits, Syminfo, Ext##Syminfo) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), si_boundto) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), si_flags) \ +END (Bits, Ext##Syminfo) + +#define Syminfo32(Ext) \ + Syminfo (32, Ext) +#define Syminfo64(Ext) \ + Syminfo (64, Ext) + +/* Move information. */ +#define Move(Bits, Ext) \ +START (Bits, Move, Ext##Move) \ + TYPE_NAME (ElfW2(Bits, Ext##Xword), m_value) \ + TYPE_NAME (ElfW2(Bits, Ext##Xword), m_info) \ + TYPE_NAME (ElfW2(Bits, Ext##Xword), m_poffset) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), m_repeat) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), m_stride) \ +END (Bits, Ext##Move) + +#define Move32(Ext) \ + Move (32, Ext) +#define Move64(Ext) \ + Move (64, Ext) + +#define Lib(Bits, Ext) \ +START (Bits, Lib, Ext##Lib) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_name) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_time_stamp) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_checksum) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_flags) \ +END (Bits, Ext##Lib) + +#define Lib32(Ext) \ + Lib (32, Ext) +#define Lib64(Ext) \ + Lib (64, Ext) + +#define auxv_t32(Ext) \ +START (32, auxv_t, Ext##auxv_t) \ + TYPE_NAME (ElfW2(32, Ext##Word), a_type) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(32, Ext##Word) a_val;) \ + TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);) \ + TYPE_EXTRA (} a_un;) \ +END (32, Ext##auxv_t) +#define auxv_t64(Ext) \ +START (64, auxv_t, Ext##auxv_t) \ + TYPE_NAME (ElfW2(64, Ext##Xword), a_type) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(64, Ext##Xword) a_val;) \ + TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);) \ + TYPE_EXTRA (} a_un;) \ +END (64, Ext##auxv_t) diff --git a/libelf/common.h b/libelf/common.h new file mode 100644 index 0000000..8eef2a7 --- /dev/null +++ b/libelf/common.h @@ -0,0 +1,184 @@ +/* Common definitions for handling files in memory or only on disk. + Copyright (C) 1998, 1999, 2000, 2002, 2005, 2008 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _COMMON_H +#define _COMMON_H 1 + +#include <ar.h> +#include <byteswap.h> +#include <endian.h> +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + +static inline Elf_Kind +__attribute__ ((unused)) +determine_kind (void *buf, size_t len) +{ + /* First test for an archive. */ + if (len >= SARMAG && memcmp (buf, ARMAG, SARMAG) == 0) + return ELF_K_AR; + + /* Next try ELF files. */ + if (len >= EI_NIDENT && memcmp (buf, ELFMAG, SELFMAG) == 0) + { + /* Could be an ELF file. */ + int eclass = (int) ((unsigned char *) buf)[EI_CLASS]; + int data = (int) ((unsigned char *) buf)[EI_DATA]; + int version = (int) ((unsigned char *) buf)[EI_VERSION]; + + if (eclass > ELFCLASSNONE && eclass < ELFCLASSNUM + && data > ELFDATANONE && data < ELFDATANUM + && version > EV_NONE && version < EV_NUM) + return ELF_K_ELF; + } + + /* We do not know this file type. */ + return ELF_K_NONE; +} + + +/* Allocate an Elf descriptor and fill in the generic information. */ +static inline Elf * +__attribute__ ((unused)) +allocate_elf (int fildes, void *map_address, off_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent, Elf_Kind kind, size_t extra) +{ + Elf *result = (Elf *) calloc (1, sizeof (Elf) + extra); + if (result == NULL) + __libelf_seterrno (ELF_E_NOMEM); + else + { + result->kind = kind; + result->ref_count = 1; + result->cmd = cmd; + result->fildes = fildes; + result->start_offset = offset; + result->maximum_size = maxsize; + result->map_address = map_address; + result->parent = parent; + + rwlock_init (result->lock); + } + + return result; +} + + +/* Acquire lock for the descriptor and all children. */ +static void +__attribute__ ((unused)) +libelf_acquire_all (Elf *elf) +{ + rwlock_wrlock (elf->lock); + + if (elf->kind == ELF_K_AR) + { + Elf *child = elf->state.ar.children; + + while (child != NULL) + { + if (child->ref_count != 0) + libelf_acquire_all (child); + child = child->next; + } + } +} + +/* Release own lock and those of the children. */ +static void +__attribute__ ((unused)) +libelf_release_all (Elf *elf) +{ + if (elf->kind == ELF_K_AR) + { + Elf *child = elf->state.ar.children; + + while (child != NULL) + { + if (child->ref_count != 0) + libelf_release_all (child); + child = child->next; + } + } + + rwlock_unlock (elf->lock); +} + + +/* Macro to convert endianess in place. It determines the function it + has to use itself. */ +#define CONVERT(Var) \ + (Var) = (sizeof (Var) == 1 \ + ? (unsigned char) (Var) \ + : (sizeof (Var) == 2 \ + ? bswap_16 (Var) \ + : (sizeof (Var) == 4 \ + ? bswap_32 (Var) \ + : bswap_64 (Var)))) + +#define CONVERT_TO(Dst, Var) \ + (Dst) = (sizeof (Var) == 1 \ + ? (unsigned char) (Var) \ + : (sizeof (Var) == 2 \ + ? bswap_16 (Var) \ + : (sizeof (Var) == 4 \ + ? bswap_32 (Var) \ + : bswap_64 (Var)))) + + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define MY_ELFDATA ELFDATA2LSB +#else +# define MY_ELFDATA ELFDATA2MSB +#endif + +#endif /* common.h */ diff --git a/libelf/dl-hash.h b/libelf/dl-hash.h new file mode 100644 index 0000000..fd59394 --- /dev/null +++ b/libelf/dl-hash.h @@ -0,0 +1,102 @@ +/* Compute hash value for given string according to ELF standard. + Copyright (C) 2006 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1995. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under an Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) and to distribute linked + combinations including the two. Non-GPL Code permitted under this + exception must only link to the code of Red Hat elfutils through those + well defined interfaces identified in the file named EXCEPTION found in + the source code files (the "Approved Interfaces"). The files of Non-GPL + Code may instantiate templates or use macros or inline functions from + the Approved Interfaces without causing the resulting work to be covered + by the GNU General Public License. Only Red Hat, Inc. may make changes + or additions to the list of Approved Interfaces. Red Hat's grant of + this exception is conditioned upon your not adding any new exceptions. + If you wish to add a new Approved Interface or exception, please contact + Red Hat. You must obey the GNU General Public License in all respects + for all of the Red Hat elfutils code and other code used in conjunction + with Red Hat elfutils except the Non-GPL Code covered by this exception. + If you modify this file, you may extend this exception to your version + of the file, but you are not obligated to do so. If you do not wish to + provide this exception without modification, you must delete this + exception statement from your version and license this file solely under + the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _DL_HASH_H +#define _DL_HASH_H 1 + + +/* This is the hashing function specified by the ELF ABI. In the + first five operations no overflow is possible so we optimized it a + bit. */ +static inline unsigned int +__attribute__ ((__pure__)) +_dl_elf_hash (const char *name) +{ + const unsigned char *iname = (const unsigned char *) name; + unsigned int hash = (unsigned int) *iname++; + if (*iname != '\0') + { + hash = (hash << 4) + (unsigned int) *iname++; + if (*iname != '\0') + { + hash = (hash << 4) + (unsigned int) *iname++; + if (*iname != '\0') + { + hash = (hash << 4) + (unsigned int) *iname++; + if (*iname != '\0') + { + hash = (hash << 4) + (unsigned int) *iname++; + while (*iname != '\0') + { + unsigned int hi; + hash = (hash << 4) + (unsigned int) *iname++; + hi = hash & 0xf0000000; + + /* The algorithm specified in the ELF ABI is as + follows: + + if (hi != 0) + hash ^= hi >> 24; + + hash &= ~hi; + + But the following is equivalent and a lot + faster, especially on modern processors. */ + + hash ^= hi; + hash ^= hi >> 24; + } + } + } + } + } + return hash; +} + +#endif /* dl-hash.h */ diff --git a/libelf/elf-knowledge.h b/libelf/elf-knowledge.h new file mode 100644 index 0000000..8b4c0d7 --- /dev/null +++ b/libelf/elf-knowledge.h @@ -0,0 +1,127 @@ +/* Accumulation of various pieces of knowledge about ELF. + Copyright (C) 2000, 2001, 2002, 2003, 2005 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _ELF_KNOWLEDGE_H +#define _ELF_KNOWLEDGE_H 1 + +#include <stdbool.h> + + +/* Test whether a section can be stripped or not. */ +#define SECTION_STRIP_P(shdr, name, remove_comment) \ + /* Sections which are allocated are not removed. */ \ + (((shdr)->sh_flags & SHF_ALLOC) == 0 \ + /* We never remove .note sections. */ \ + && (shdr)->sh_type != SHT_NOTE \ + && (((shdr)->sh_type) != SHT_PROGBITS \ + /* Never remove .gnu.warning.* sections. */ \ + || (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) != 0 \ + /* We remove .comment sections only if explicitly told to do so. */\ + && (remove_comment \ + || strcmp (name, ".comment") != 0))) \ + /* So far we do not remove any of the non-standard sections. \ + XXX Maybe in future. */ \ + && (shdr)->sh_type < SHT_NUM) + + +/* Test whether `sh_info' field in section header contains a section + index. There are two kinds of sections doing this: + + - the sections containing relocation information reference in this + field the section to which the relocations apply; + + - section with the SHF_INFO_LINK flag set to signal that `sh_info' + references a section. This allows correct handling of unknown + sections. */ +#define SH_INFO_LINK_P(Shdr) \ + ((Shdr)->sh_type == SHT_REL || (Shdr)->sh_type == SHT_RELA \ + || ((Shdr)->sh_flags & SHF_INFO_LINK) != 0) + + +/* When combining ELF section flags we must distinguish two kinds: + + - flags which cause problem if not added to the result even if not + present in all input sections + + - flags which cause problem if added to the result if not present + in all input sections + + The following definition is for the general case. There might be + machine specific extensions. */ +#define SH_FLAGS_COMBINE(Flags1, Flags2) \ + (((Flags1 | Flags2) \ + & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_LINK_ORDER \ + | SHF_OS_NONCONFORMING | SHF_GROUP)) \ + | (Flags1 & Flags2 & (SHF_MERGE | SHF_STRINGS | SHF_INFO_LINK))) + +/* Similar macro: return the bits of the flags which necessarily must + match if two sections are automatically combined. Sections still + can be forcefully combined in which case SH_FLAGS_COMBINE can be + used to determine the combined flags. */ +#define SH_FLAGS_IMPORTANT(Flags) \ + ((Flags) & ~((GElf_Xword) 0 | SHF_LINK_ORDER | SHF_OS_NONCONFORMING)) + + +/* Size of an entry in the hash table. The ELF specification says all + entries are regardless of platform 32-bits in size. Early 64-bit + ports (namely Alpha for Linux) got this wrong. The wording was not + clear. + + Several years later the ABI for the 64-bit S390s was developed. + Many things were copied from the IA-64 ABI (which uses the correct + 32-bit entry size) but what do these people do? They use 64-bit + entries. It is really shocking to see what kind of morons are out + there. And even worse: they are allowed to design ABIs. */ +#define SH_ENTSIZE_HASH(Ehdr) \ + ((Ehdr)->e_machine == EM_ALPHA \ + || ((Ehdr)->e_machine == EM_S390 \ + && (Ehdr)->e_ident[EI_CLASS] == ELFCLASS64) ? 8 : 4) + +#endif /* elf-knowledge.h */ diff --git a/libelf/elf.h b/libelf/elf.h new file mode 100644 index 0000000..a9558a3 --- /dev/null +++ b/libelf/elf.h @@ -0,0 +1,2799 @@ +/* This file defines standard ELF types, structures, and macros. + Copyright (C) 1995-2003,2004,2005,2006,2007,2008,2009,2010 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _ELF_H +#define _ELF_H 1 + +#include <features.h> + +__BEGIN_DECLS + +/* Standard ELF types. */ + +#include <stdint.h> + +/* Type for a 16-bit quantity. */ +typedef uint16_t Elf32_Half; +typedef uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef uint32_t Elf32_Addr; +typedef uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef uint16_t Elf32_Section; +typedef uint16_t Elf64_Section; + +/* Type for version symbol information. */ +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_LINUX 3 /* Linux. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ + +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_NUM 95 + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_BEFORE 0xff00 /* Order section before all others + (Solaris). */ +#define SHN_AFTER 0xff01 /* Order section after all others + (Solaris). */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_LOOS 0xff20 /* Start of OS-specific */ +#define SHN_HIOS 0xff3f /* End of OS-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_XINDEX 0xffff /* Index is in extra table. */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific. */ +#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ +#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling + required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_ORDERED (1 << 30) /* Special ordering requirement + (Solaris). */ +#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless + referenced or allocated (Solaris).*/ + +/* Section group handling. */ +#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf32_Section st_shndx; /* Section index */ +} Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ + +typedef struct +{ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ +} Elf32_Syminfo; + +typedef struct +{ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ +} Elf64_Syminfo; + +/* Possible values for si_boundto. */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ + +/* Possible bitmasks for si_flags. */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ +/* Syminfo version values. */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_GNU_UNIQUE 10 /* Unique symbol. */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ + + +/* How to extract and insert information held in the st_other field. */ + +#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) + +/* For ELF64 the definitions are the same. */ +#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) + +/* Symbol visibility specification encoded in the st_other field. */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Special value for e_phnum. This indicates that the real number of + program headers is too large to fit into e_phnum. Instead the real + value is in the field sh_info of section 0. */ + +#define PN_XNUM 0xffff + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKOS 0x0ff00000 /* OS-specific */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Legal values for note segment descriptor types for core files. */ + +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_ASRS 8 /* Contains copy of asrset struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ +#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ +#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ +#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ +#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ +#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ +#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ + + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + +/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's + approach. */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ +#define DT_TLSDESC_PLT 0x6ffffef6 +#define DT_TLSDESC_GOT 0x6ffffef7 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 11 + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ + +/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 + entry in the dynamic section. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ + +/* Flags for the feature selection in DT_FEATURE_1. */ +#define DTF_1_PARINIT 0x00000001 +#define DTF_1_CONFEXP 0x00000002 + +/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not + generally available. */ + +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +typedef struct +{ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf64_Verdef; + + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Versym symbol index values. */ +#define VER_NDX_LOCAL 0 /* Symbol is local. */ +#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ + +/* Auxialiary version information. */ + +typedef struct +{ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +typedef struct +{ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf64_Verdaux; + + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +typedef struct +{ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf64_Verneed; + + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +typedef struct +{ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf64_Vernaux; + + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard <elf.h> file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + uint32_t a_type; /* Entry type */ + union + { + uint32_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + uint64_t a_type; /* Entry type */ + union + { + uint64_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ + } a_un; +} Elf64_auxv_t; + +/* Legal values for a_type (entry type). */ + +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Real gid */ +#define AT_EGID 14 /* Effective gid */ +#define AT_CLKTCK 17 /* Frequency of times() */ + +/* Some more special a_type values describing the hardware. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine dependent hints about + processor capabilities. */ + +/* This entry gives some information about the FPU initialization + performed by the kernel. */ +#define AT_FPUCW 18 /* Used FPU control word. */ + +/* Cache block sizes. */ +#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ + +/* A special ignored value for PPC, used by the kernel to control the + interpretation of the AUXV. Must be > 16. */ +#define AT_IGNOREPPC 22 /* Entry should be ignored. */ + +#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ + +#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ + +#define AT_RANDOM 25 /* Address of 16 random bytes. */ + +#define AT_EXECFN 31 /* Filename of executable. */ + +/* Pointer to the global system page used for system calls and other + nice things. */ +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 + +/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains + log2 of line size; mask those to get cache size. */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 +#define AT_L3_CACHESHAPE 37 + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define NT_GNU_ABI_TAG 1 +#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ + +/* Known OSes. These values can appear in word 0 of an + NT_GNU_ABI_TAG note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 +#define ELF_NOTE_OS_FREEBSD 3 + +/* Synthetic hwcap information. The descriptor begins with two words: + word 0: number of entries + word 1: bitmask of enabled entries + Then follow variable-length entries, one byte followed by a + '\0'-terminated hwcap name string. The byte gives the bit + number to test if enabled, (1U << bit) & bitmask. */ +#define NT_GNU_HWCAP 2 + +/* Build ID bits as generated by ld --build-id. + The descriptor consists of any nonzero number of bytes. */ +#define NT_GNU_BUILD_ID 3 + +/* Version note generated by GNU gold containing a version string. */ +#define NT_GNU_GOLD_VERSION 4 + + +/* Move records. */ +typedef struct +{ + Elf32_Xword m_value; /* Symbol value. */ + Elf32_Word m_info; /* Size and index. */ + Elf32_Word m_poffset; /* Symbol offset. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Stride info. */ +} Elf32_Move; + +typedef struct +{ + Elf64_Xword m_value; /* Symbol value. */ + Elf64_Xword m_info; /* Size and index. */ + Elf64_Xword m_poffset; /* Symbol offset. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Stride info. */ +} Elf64_Move; + +/* Macro to construct move records. */ +#define ELF32_M_SYM(info) ((info) >> 8) +#define ELF32_M_SIZE(info) ((unsigned char) (info)) +#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) + +#define ELF64_M_SYM(info) ELF32_M_SYM (info) +#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) + + +/* Motorola 68k specific definitions. */ + +/* Values for Elf32_Ehdr.e_flags. */ +#define EF_CPU32 0x00810000 + +/* m68k relocs. */ + +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ +#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ +#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ +#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ +#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ +#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ +#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ +#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ +#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ +#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ +#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ +#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ +#define R_68K_TLS_LE32 37 /* 32 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE16 38 /* 16 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE8 39 /* 8 bit offset relative to + static TLS block */ +#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ +#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ +#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ +/* Keep this the last entry. */ +#define R_68K_NUM 43 + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* 38? */ +#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ +#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS + descriptor for + relaxation. */ +#define R_386_TLS_DESC 41 /* TLS descriptor containing + pointer to code and to + argument, returning the TLS + offset for the symbol. */ +#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ +/* Keep this the last entry. */ +#define R_386_NUM 43 + +/* SUN SPARC specific definitions. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* Additional Sparc64 relocs. */ + +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +#define R_SPARC_GOTDATA_HIX22 80 +#define R_SPARC_GOTDATA_LOX10 81 +#define R_SPARC_GOTDATA_OP_HIX22 82 +#define R_SPARC_GOTDATA_OP_LOX10 83 +#define R_SPARC_GOTDATA_OP 84 +#define R_SPARC_H34 85 +#define R_SPARC_SIZE32 86 +#define R_SPARC_SIZE64 87 +#define R_SPARC_JMP_IREL 248 +#define R_SPARC_IRELATIVE 249 +#define R_SPARC_GNU_VTINHERIT 250 +#define R_SPARC_GNU_VTENTRY 251 +#define R_SPARC_REV32 252 +/* Keep this the last entry. */ +#define R_SPARC_NUM 253 + +/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ + +#define DT_SPARC_REGISTER 0x70000001 +#define DT_SPARC_NUM 2 + +/* Bits present in AT_HWCAP on SPARC. */ + +#define HWCAP_SPARC_FLUSH 1 /* The CPU supports flush insn. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 /* The CPU is v9, so v8plus is ok. */ +#define HWCAP_SPARC_ULTRA3 32 +#define HWCAP_SPARC_BLKINIT 64 /* Sun4v with block-init/load-twin. */ +#define HWCAP_SPARC_N2 128 + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* The following are non-official names and should not be used. */ + +#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRINGS 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 + + +/* Symbol tables. */ + +/* MIPS specific values for `st_other'. */ +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_PLT 0x8 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff + +/* MIPS specific values for `st_info'. */ +#define STB_MIPS_SPLIT_COMMON 13 + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ +} Elf32_RegInfo; + +/* Entries found in sections of type SHT_MIPS_OPTIONS. */ + +typedef struct +{ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* Values for `kind' field in Elf_Options. */ + +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ + +/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ + +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ + +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 + +/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ + +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ + +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 + +/* Entry found in `.options' section. */ + +typedef struct +{ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ +} Elf_Options_Hw; + +/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ + +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ +#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ +#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ +#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ +#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ +#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ +#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ +#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ +#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ +#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ +#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ +#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ +#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ +#define R_MIPS_GLOB_DAT 51 +#define R_MIPS_COPY 126 +#define R_MIPS_JUMP_SLOT 127 +/* Keep this the last entry. */ +#define R_MIPS_NUM 128 + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in + DT_MIPS_DELTA_CLASS. */ +#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in + DT_MIPS_DELTA_INSTANCE. */ +#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in + DT_MIPS_DELTA_RELOC. */ +#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta + relocations refer to. */ +#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in + DT_MIPS_DELTA_SYM. */ +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the + class declaration. */ +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in + DT_MIPS_DELTA_CLASSSYM. */ +#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve + function stored in GOT. */ +#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added + by rld on dlopen() calls. */ +#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +/* The address of .got.plt in an executable using the new non-PIC ABI. */ +#define DT_MIPS_PLTGOT 0x70000032 +/* The base of the PLT in an executable using the new non-PIC ABI if that + PLT is writable. For a non-writable PLT, this is omitted or has a zero + value. */ +#define DT_MIPS_RWPLT 0x70000034 +#define DT_MIPS_NUM 0x35 + +/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_GUARANTEE_START_INIT (1 << 7) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +typedef struct +{ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ +} Elf64_Lib; + + +/* Legal values for l_flags. */ + +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_REQUIRE_MINOR (1 << 2) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indeces. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ +#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_GNU_VTENTRY 232 +#define R_PARISC_GNU_VTINHERIT 233 +#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ +#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ +#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ +#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ +#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ +#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ +#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ +#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ +#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ +#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ +#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L +#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R +#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L +#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R +#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 +#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + +/* Legal values for sh_type field of Elf64_Shdr. */ + +/* These two are primerily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 + +/* Legal values for sh_flags field of Elf64_Shdr. */ + +#define SHF_ALPHA_GPREL 0x10000000 + +/* Legal values for st_other field of Elf64_Sym. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_TLS_GD_HI 28 +#define R_ALPHA_TLSGD 29 +#define R_ALPHA_TLS_LDM 30 +#define R_ALPHA_DTPMOD64 31 +#define R_ALPHA_GOTDTPREL 32 +#define R_ALPHA_DTPREL64 33 +#define R_ALPHA_DTPRELHI 34 +#define R_ALPHA_DTPRELLO 35 +#define R_ALPHA_DTPREL16 36 +#define R_ALPHA_GOTTPREL 37 +#define R_ALPHA_TPREL64 38 +#define R_ALPHA_TPRELHI 39 +#define R_ALPHA_TPRELLO 40 +#define R_ALPHA_TPREL16 41 +/* Keep this the last entry. */ +#define R_ALPHA_NUM 46 + +/* Magic values of the LITUSE relocation addend. */ +#define LITUSE_ALPHA_ADDR 0 +#define LITUSE_ALPHA_BASE 1 +#define LITUSE_ALPHA_BYTOFF 2 +#define LITUSE_ALPHA_JSR 3 +#define LITUSE_ALPHA_TLS_GD 4 +#define LITUSE_ALPHA_TLS_LDM 5 + +/* Legal values for d_tag of Elf64_Dyn. */ +#define DT_ALPHA_PLTRO (DT_LOPROC + 0) +#define DT_ALPHA_NUM 1 + +/* PowerPC specific declarations */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +/* PowerPC relocations defined for the TLS access ABI. */ +#define R_PPC_TLS 67 /* none (sym+add)@tls */ +#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ +#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ +#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ +#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ +#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ +#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ +#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ +#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ +#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* GNU extension to support local ifunc. */ +#define R_PPC_IRELATIVE 248 + +/* GNU relocs used in PIC code sequences. */ +#define R_PPC_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + +/* PowerPC specific values for the Dyn d_tag field. */ +#define DT_PPC_GOT (DT_LOPROC + 0) +#define DT_PPC_NUM 1 + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ + +/* PowerPC64 relocations defined for the TLS access ABI. */ +#define R_PPC64_TLS 67 /* none (sym+add)@tls */ +#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ +#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ +#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ +#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ +#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ +#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ +#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ +#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ +#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ +#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ +#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ +#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ +#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ +#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ +#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ +#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ +#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ + +/* GNU extension to support local ifunc. */ +#define R_PPC64_JMP_IREL 247 +#define R_PPC64_IRELATIVE 248 +#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ + +/* PowerPC64 specific values for the Dyn d_tag field. */ +#define DT_PPC64_GLINK (DT_LOPROC + 0) +#define DT_PPC64_OPD (DT_LOPROC + 1) +#define DT_PPC64_OPDSZ (DT_LOPROC + 2) +#define DT_PPC64_NUM 3 + + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 +#define EF_ARM_SOFT_FLOAT 0x200 +#define EF_ARM_VFP_FLOAT 0x400 +#define EF_ARM_MAVERICK_FLOAT 0x800 + + +/* Other constants defined in the ARM ELF spec. version B-01. */ +/* NB. These conflict with values defined above. */ +#define EF_ARM_SYMSARESORTED 0x04 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_MAPSYMSFIRST 0x10 +#define EF_ARM_EABIMASK 0XFF000000 + +/* Constants defined in AAELF. */ +#define EF_ARM_BE8 0x00800000 +#define EF_ARM_LE8 0x00400000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 +#define EF_ARM_EABI_VER3 0x03000000 +#define EF_ARM_EABI_VER4 0x04000000 +#define EF_ARM_EABI_VER5 0x05000000 + +/* Additional symbol types for Thumb. */ +#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ +#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ + +/* ARM-specific values for sh_flags */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step. */ + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base. */ +#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ +#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ +#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ +#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ + + +/* ARM relocs. */ + +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ +#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ +#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0 35 +#define R_ARM_ALU_SBREL_19_12 36 +#define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic + thread local data */ +#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic + thread local data */ +#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS + block */ +#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of + static TLS block offset */ +#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static + TLS block */ +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +/* IA-64 specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ +#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) +#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) +#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) + +/* Processor specific flags for the Phdr p_flags field. */ +#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ + +/* Processor specific flags for the Shdr sh_flags field. */ +#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Dyn d_tag field. */ +#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +#define DT_IA_64_NUM 1 + +/* IA-64 relocations. */ +#define R_IA64_NONE 0x00 /* none */ +#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +#define R_IA64_COPY 0x84 /* copy relocation */ +#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ + +/* SH specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_SH_MACH_MASK 0x1f +#define EF_SH_UNKNOWN 0x0 +#define EF_SH1 0x1 +#define EF_SH2 0x2 +#define EF_SH3 0x3 +#define EF_SH_DSP 0x4 +#define EF_SH3_DSP 0x5 +#define EF_SH4AL_DSP 0x6 +#define EF_SH3E 0x8 +#define EF_SH4 0x9 +#define EF_SH2E 0xb +#define EF_SH4A 0xc +#define EF_SH2A 0xd +#define EF_SH4_NOFPU 0x10 +#define EF_SH4A_NOFPU 0x11 +#define EF_SH4_NOMMU_NOFPU 0x12 +#define EF_SH2A_NOFPU 0x13 +#define EF_SH3_NOMMU 0x14 +#define EF_SH2A_SH4_NOFPU 0x15 +#define EF_SH2A_SH3_NOFPU 0x16 +#define EF_SH2A_SH4 0x17 +#define EF_SH2A_SH3E 0x18 + +/* SH relocs. */ +#define R_SH_NONE 0 +#define R_SH_DIR32 1 +#define R_SH_REL32 2 +#define R_SH_DIR8WPN 3 +#define R_SH_IND12W 4 +#define R_SH_DIR8WPL 5 +#define R_SH_DIR8WPZ 6 +#define R_SH_DIR8BP 7 +#define R_SH_DIR8W 8 +#define R_SH_DIR8L 9 +#define R_SH_SWITCH16 25 +#define R_SH_SWITCH32 26 +#define R_SH_USES 27 +#define R_SH_COUNT 28 +#define R_SH_ALIGN 29 +#define R_SH_CODE 30 +#define R_SH_DATA 31 +#define R_SH_LABEL 32 +#define R_SH_SWITCH8 33 +#define R_SH_GNU_VTINHERIT 34 +#define R_SH_GNU_VTENTRY 35 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_GOT32 160 +#define R_SH_PLT32 161 +#define R_SH_COPY 162 +#define R_SH_GLOB_DAT 163 +#define R_SH_JMP_SLOT 164 +#define R_SH_RELATIVE 165 +#define R_SH_GOTOFF 166 +#define R_SH_GOTPC 167 +/* Keep this the last entry. */ +#define R_SH_NUM 256 + +/* S/390 specific definitions. */ + +/* Valid values for the e_flags field. */ + +#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ + +/* Additional s390 relocs */ + +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ +#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ +#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ +#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ +#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ +#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ +#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ +#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ +#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ +#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ +#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ +#define R_390_TLS_GDCALL 38 /* Tag for function call in general + dynamic TLS code. */ +#define R_390_TLS_LDCALL 39 /* Tag for function call in local + dynamic TLS code. */ +#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic + thread local data. */ +#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic + thread local data. */ +#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS + block. */ +#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS + block. */ +#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ +#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ +#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS + block. */ +#define R_390_20 57 /* Direct 20 bit. */ +#define R_390_GOT20 58 /* 20 bit GOT offset. */ +#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS + block offset. */ +/* Keep this the last entry. */ +#define R_390_NUM 61 + + +/* CRIS relocations. */ +#define R_CRIS_NONE 0 +#define R_CRIS_8 1 +#define R_CRIS_16 2 +#define R_CRIS_32 3 +#define R_CRIS_8_PCREL 4 +#define R_CRIS_16_PCREL 5 +#define R_CRIS_32_PCREL 6 +#define R_CRIS_GNU_VTINHERIT 7 +#define R_CRIS_GNU_VTENTRY 8 +#define R_CRIS_COPY 9 +#define R_CRIS_GLOB_DAT 10 +#define R_CRIS_JUMP_SLOT 11 +#define R_CRIS_RELATIVE 12 +#define R_CRIS_16_GOT 13 +#define R_CRIS_32_GOT 14 +#define R_CRIS_16_GOTPLT 15 +#define R_CRIS_32_GOTPLT 16 +#define R_CRIS_32_GOTREL 17 +#define R_CRIS_32_PLT_GOTREL 18 +#define R_CRIS_32_PLT_PCREL 19 + +#define R_CRIS_NUM 20 + + +/* AMD x86-64 relocations. */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ +#define R_X86_64_PC64 24 /* PC relative 64 bit */ +#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ +#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative + offset to GOT */ +#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ +#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset + to GOT entry */ +#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ +#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ +#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset + to PLT entry */ +#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ +#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ +#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ +#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS + descriptor. */ +#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ +#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ + +#define R_X86_64_NUM 38 + + +/* AM33 relocations. */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ +#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ +#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ +#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ +#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ +#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ +#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ +#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ +#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ +#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ +#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ +#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ +#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ +#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ + +#define R_MN10300_NUM 24 + + +/* M32R relocs. */ +#define R_M32R_NONE 0 /* No reloc. */ +#define R_M32R_16 1 /* Direct 16 bit. */ +#define R_M32R_32 2 /* Direct 32 bit. */ +#define R_M32R_24 3 /* Direct 24 bit. */ +#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ +#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ +#define R_M32R_LO16 9 /* Low 16 bit. */ +#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ +#define R_M32R_GNU_VTINHERIT 11 +#define R_M32R_GNU_VTENTRY 12 +/* M32R relocs use SHT_RELA. */ +#define R_M32R_16_RELA 33 /* Direct 16 bit. */ +#define R_M32R_32_RELA 34 /* Direct 32 bit. */ +#define R_M32R_24_RELA 35 /* Direct 24 bit. */ +#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ +#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ +#define R_M32R_LO16_RELA 41 /* Low 16 bit */ +#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ +#define R_M32R_RELA_GNU_VTINHERIT 43 +#define R_M32R_RELA_GNU_VTENTRY 44 +#define R_M32R_REL32 45 /* PC relative 32 bit. */ + +#define R_M32R_GOT24 48 /* 24 bit GOT entry */ +#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ +#define R_M32R_COPY 50 /* Copy symbol at runtime */ +#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ +#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ +#define R_M32R_RELATIVE 53 /* Adjust by program base */ +#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ +#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ +#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned + low */ +#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed + low */ +#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ +#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to + GOT with unsigned low */ +#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to + GOT with signed low */ +#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to + GOT */ +#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT + with unsigned low */ +#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT + with signed low */ +#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ +#define R_M32R_NUM 256 /* Keep this the last entry. */ + + +__END_DECLS + +#endif /* elf.h */ diff --git a/libelf/elf32_checksum.c b/libelf/elf32_checksum.c new file mode 100644 index 0000000..ad040b8 --- /dev/null +++ b/libelf/elf32_checksum.c @@ -0,0 +1,195 @@ +/* Compute simple checksum from permanent parts of the ELF file. + Copyright (C) 2002, 2003, 2004, 2005, 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <endian.h> +#include <stdbool.h> +#include <stddef.h> +#include <string.h> + +#include "gelf.h" +#include "libelfP.h" +#include "elf-knowledge.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +/* The SECTION_STRIP_P macro wants to call into libebl which we cannot + do and do not have to do here. Provide a dummy replacement. */ +#define ebl_debugscn_p(ebl, name) true + + +#define process_block(crc, data) \ + __libelf_crc32 (crc, data->d_buf, data->d_size) + + +long int +elfw2(LIBELFBITS,checksum) (elf) + Elf *elf; +{ + size_t shstrndx; + Elf_Scn *scn; + long int result = 0; + unsigned char *ident; + bool same_byte_order; + + if (elf == NULL) + return -1l; + + /* Find the section header string table. */ + if (INTUSE(elf_getshdrstrndx) (elf, &shstrndx) < 0) + { + /* This can only happen if the ELF handle is not for real. */ + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1l; + } + + /* Determine whether the byte order of the file and that of the host + is the same. */ + ident = elf->state.ELFW(elf,LIBELFBITS).ehdr->e_ident; + same_byte_order = ((ident[EI_DATA] == ELFDATA2LSB + && __BYTE_ORDER == __LITTLE_ENDIAN) + || (ident[EI_DATA] == ELFDATA2MSB + && __BYTE_ORDER == __BIG_ENDIAN)); + + /* If we don't have native byte order, we will likely need to + convert the data with xlate functions. We do it upfront instead + of relocking mid-iteration. */ + if (!likely (same_byte_order)) + rwlock_wrlock (elf->lock); + else + rwlock_rdlock (elf->lock); + + /* Iterate over all sections to find those which are not strippable. */ + scn = NULL; + while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + Elf_Data *data; + + /* Get the section header. */ + shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem); + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + result = -1l; + goto out; + } + + if (SECTION_STRIP_P (shdr, + INTUSE(elf_strptr) (elf, shstrndx, shdr->sh_name), + true)) + /* The section can be stripped. Don't use it. */ + continue; + + /* Do not look at NOBITS sections. */ + if (shdr->sh_type == SHT_NOBITS) + continue; + + /* To compute the checksum we need to get to the data. For + repeatable results we must use the external format. The data + we get with 'elf'getdata' might be changed for endianess + reasons. Therefore we use 'elf_rawdata' if possible. But + this function can fail if the data was constructed by the + program. In this case we have to use 'elf_getdata' and + eventually convert the data to the external format. */ + data = INTUSE(elf_rawdata) (scn, NULL); + if (data != NULL) + { + /* The raw data is available. */ + result = process_block (result, data); + + /* Maybe the user added more data. These blocks cannot be + read using 'elf_rawdata'. Simply proceed with looking + for more data block with 'elf_getdata'. */ + } + + /* Iterate through the list of data blocks. */ + while ((data = INTUSE(elf_getdata) (scn, data)) != NULL) + /* If the file byte order is the same as the host byte order + process the buffer directly. If the data is just a stream + of bytes which the library will not convert we can use it + as well. */ + if (likely (same_byte_order) || data->d_type == ELF_T_BYTE) + result = process_block (result, data); + else + { + /* Convert the data to file byte order. */ + if (INTUSE(elfw2(LIBELFBITS,xlatetof)) (data, data, ident[EI_DATA]) + == NULL) + { + result = -1l; + goto out; + } + + result = process_block (result, data); + + /* And convert it back. */ + if (INTUSE(elfw2(LIBELFBITS,xlatetom)) (data, data, ident[EI_DATA]) + == NULL) + { + result = -1l; + goto out; + } + } + } + + out: + rwlock_unlock (elf->lock); + return result; +} +INTDEF(elfw2(LIBELFBITS,checksum)) diff --git a/libelf/elf32_fsize.c b/libelf/elf32_fsize.c new file mode 100644 index 0000000..3189045 --- /dev/null +++ b/libelf/elf32_fsize.c @@ -0,0 +1,92 @@ +/* Return the size of an object file type. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +size_t +elfw2(LIBELFBITS, fsize) (type, count, version) + Elf_Type type; + size_t count; + unsigned int version; +{ + /* We do not have differences between file and memory sizes. Better + not since otherwise `mmap' would not work. */ + if (unlikely (version == EV_NONE) || unlikely (version >= EV_NUM)) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return 0; + } + + if (unlikely (type >= ELF_T_NUM)) + { + __libelf_seterrno (ELF_E_UNKNOWN_TYPE); + return 0; + } + +#if EV_NUM != 2 + return (count + * __libelf_type_sizes[version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][type]); +#else + return (count + * __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][type]); +#endif +} +#define local_strong_alias(n1, n2) strong_alias (n1, n2) +local_strong_alias (elfw2(LIBELFBITS, fsize), __elfw2(LIBELFBITS, msize)) diff --git a/libelf/elf32_getehdr.c b/libelf/elf32_getehdr.c new file mode 100644 index 0000000..8009133 --- /dev/null +++ b/libelf/elf32_getehdr.c @@ -0,0 +1,120 @@ +/* Get ELF header. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +static ElfW2(LIBELFBITS,Ehdr) * +getehdr_impl (elf, wrlock) + Elf *elf; + int wrlock; +{ + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + again: + if (elf->class == 0) + { + if (!wrlock) + { + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + wrlock = 1; + goto again; + } + elf->class = ELFW(ELFCLASS,LIBELFBITS); + } + else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + return NULL; + } + + return elf->state.ELFW(elf,LIBELFBITS).ehdr; +} + +ElfW2(LIBELFBITS,Ehdr) * +__elfw2(LIBELFBITS,getehdr_wrlock) (elf) + Elf *elf; +{ + return getehdr_impl (elf, 1); +} + +ElfW2(LIBELFBITS,Ehdr) * +elfw2(LIBELFBITS,getehdr) (elf) + Elf *elf; +{ + ElfW2(LIBELFBITS,Ehdr) *result; + if (elf == NULL) + return NULL; + + rwlock_rdlock (elf->lock); + result = getehdr_impl (elf, 0); + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c new file mode 100644 index 0000000..80f54fd --- /dev/null +++ b/libelf/elf32_getphdr.c @@ -0,0 +1,266 @@ +/* Get ELF program header table. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> + +#include <system.h> +#include "libelfP.h" +#include "common.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + +ElfW2(LIBELFBITS,Phdr) * +__elfw2(LIBELFBITS,getphdr_wrlock) (elf) + Elf *elf; +{ + ElfW2(LIBELFBITS,Phdr) *result; + + /* If the program header entry has already been filled in the code + below must already have been run. So the class is set, too. No + need to waste any more time here. */ + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + if (likely (result != NULL)) + return result; + + if (elf->class == 0) + elf->class = ELFW(ELFCLASS,LIBELFBITS); + else if (elf->class != ELFW(ELFCLASS,LIBELFBITS)) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + result = NULL; + goto out; + } + + if (likely (result == NULL)) + { + /* Read the section header table. */ + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* If no program header exists return NULL. */ + size_t phnum; + if (__elf_getphdrnum_rdlock (elf, &phnum) != 0) + goto out; + if (phnum == 0) + { + __libelf_seterrno (ELF_E_NO_PHDR); + goto out; + } + + size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr)); + + if (ehdr->e_phoff > elf->maximum_size + || elf->maximum_size - ehdr->e_phoff < size) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + if (elf->map_address != NULL) + { + /* All the data is already mapped. Use it. */ + void *file_phdr = ((char *) elf->map_address + + elf->start_offset + ehdr->e_phoff); + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || ((uintptr_t) file_phdr + & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0)) + /* Simply use the mapped data. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr; + else + { + ElfW2(LIBELFBITS,Phdr) *notcvt; + ElfW2(LIBELFBITS,Phdr) *phdr; + + /* Allocate memory for the program headers. We know the number + of entries from the ELF header. */ + phdr = elf->state.ELFW(elf,LIBELFBITS).phdr = + (ElfW2(LIBELFBITS,Phdr) *) malloc (size); + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= + ELF_F_MALLOCED | ELF_F_DIRTY; + + /* Now copy the data and at the same time convert the + byte order. */ + + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA) + { + assert (! ALLOW_UNALIGNED); + memcpy (phdr, file_phdr, size); + } + else + { + if (ALLOW_UNALIGNED + || ((uintptr_t) file_phdr + & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0) + notcvt = file_phdr; + else + { + notcvt = (ElfW2(LIBELFBITS,Phdr) *) alloca (size); + memcpy (notcvt, file_phdr, size); + } + + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type); + CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset); + CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr); + CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr); + CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz); + CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz); + CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags); + CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align); + } + } + } + } + else if (likely (elf->fildes != -1)) + { + /* Allocate memory for the program headers. We know the number + of entries from the ELF header. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = + (ElfW2(LIBELFBITS,Phdr) *) malloc (size); + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED; + + /* Read the header. */ + ssize_t n = pread_retry (elf->fildes, + elf->state.ELFW(elf,LIBELFBITS).phdr, size, + elf->start_offset + ehdr->e_phoff); + if (unlikely ((size_t) n != size)) + { + /* Severe problems. We cannot read the data. */ + __libelf_seterrno (ELF_E_READ_ERROR); + free (elf->state.ELFW(elf,LIBELFBITS).phdr); + elf->state.ELFW(elf,LIBELFBITS).phdr = NULL; + goto out; + } + + /* If the byte order of the file is not the same as the one + of the host convert the data now. */ + if (ehdr->e_ident[EI_DATA] != MY_ELFDATA) + { + ElfW2(LIBELFBITS,Phdr) *phdr + = elf->state.ELFW(elf,LIBELFBITS).phdr; + + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + CONVERT (phdr[cnt].p_type); + CONVERT (phdr[cnt].p_offset); + CONVERT (phdr[cnt].p_vaddr); + CONVERT (phdr[cnt].p_paddr); + CONVERT (phdr[cnt].p_filesz); + CONVERT (phdr[cnt].p_memsz); + CONVERT (phdr[cnt].p_flags); + CONVERT (phdr[cnt].p_align); + } + } + } + else + { + /* The file descriptor was already enabled and not all data was + read. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + goto out; + } + + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + } + + out: + return result; +} + +ElfW2(LIBELFBITS,Phdr) * +elfw2(LIBELFBITS,getphdr) (elf) + Elf *elf; +{ + ElfW2(LIBELFBITS,Phdr) *result; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* If the program header entry has already been filled in the code + * in getphdr_wrlock must already have been run. So the class is + * set, too. No need to waste any more time here. */ + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + if (likely (result != NULL)) + return result; + + rwlock_wrlock (elf->lock); + result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf); + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,getphdr)) diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c new file mode 100644 index 0000000..8d650d9 --- /dev/null +++ b/libelf/elf32_getshdr.c @@ -0,0 +1,294 @@ +/* Return section header. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <unistd.h> + +#include <system.h> +#include "libelfP.h" +#include "common.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +static ElfW2(LIBELFBITS,Shdr) * +load_shdr_wrlock (Elf_Scn *scn) +{ + ElfW2(LIBELFBITS,Shdr) *result; + + /* Read the section header table. */ + Elf *elf = scn->elf; + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* Try again, maybe the data is there now. */ + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result != NULL) + goto out; + + size_t shnum; + if (__elf_getshdrnum_rdlock (elf, &shnum) != 0) + goto out; + size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr)); + + /* Allocate memory for the section headers. We know the number + of entries from the ELF header. */ + ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr = + (ElfW2(LIBELFBITS,Shdr) *) malloc (size); + if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1; + + if (elf->map_address != NULL) + { + ElfW2(LIBELFBITS,Shdr) *notcvt; + + /* All the data is already mapped. If we could use it + directly this would already have happened. */ + void *file_shdr = ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff); + + assert (ehdr->e_ident[EI_DATA] != MY_ELFDATA + || (! ALLOW_UNALIGNED + && ((uintptr_t) file_shdr + & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0)); + + /* Now copy the data and at the same time convert the byte order. */ + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA) + { + assert (! ALLOW_UNALIGNED); + memcpy (shdr, file_shdr, size); + } + else + { + if (ALLOW_UNALIGNED + || ((uintptr_t) file_shdr + & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0) + notcvt = (ElfW2(LIBELFBITS,Shdr) *) + ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff); + else + { + notcvt = (ElfW2(LIBELFBITS,Shdr) *) alloca (size); + memcpy (notcvt, ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff), + size); + } + + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name); + CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type); + CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags); + CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr); + CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset); + CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size); + CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link); + CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info); + CONVERT_TO (shdr[cnt].sh_addralign, + notcvt[cnt].sh_addralign); + CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize); + + /* If this is a section with an extended index add a + reference in the section which uses the extended + index. */ + if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX + && shdr[cnt].sh_link < shnum) + elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index + = cnt; + + /* Set the own shndx_index field in case it has not yet + been set. */ + if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0) + elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index + = -1; + } + } + } + else if (likely (elf->fildes != -1)) + { + /* Read the header. */ + ssize_t n = pread_retry (elf->fildes, + elf->state.ELFW(elf,LIBELFBITS).shdr, size, + elf->start_offset + ehdr->e_shoff); + if (unlikely ((size_t) n != size)) + { + /* Severe problems. We cannot read the data. */ + __libelf_seterrno (ELF_E_READ_ERROR); + goto free_and_out; + } + + /* If the byte order of the file is not the same as the one + of the host convert the data now. */ + if (ehdr->e_ident[EI_DATA] != MY_ELFDATA) + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + CONVERT (shdr[cnt].sh_name); + CONVERT (shdr[cnt].sh_type); + CONVERT (shdr[cnt].sh_flags); + CONVERT (shdr[cnt].sh_addr); + CONVERT (shdr[cnt].sh_offset); + CONVERT (shdr[cnt].sh_size); + CONVERT (shdr[cnt].sh_link); + CONVERT (shdr[cnt].sh_info); + CONVERT (shdr[cnt].sh_addralign); + CONVERT (shdr[cnt].sh_entsize); + } + } + else + { + /* The file descriptor was already enabled and not all data was + read. Undo the allocation. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + + free_and_out: + free (shdr); + elf->state.ELFW(elf,LIBELFBITS).shdr = NULL; + elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0; + + goto out; + } + + /* Set the pointers in the `scn's. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS) + = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt]; + + result = scn->shdr.ELFW(e,LIBELFBITS); + assert (result != NULL); + +out: + return result; +} + +static bool +scn_valid (Elf_Scn *scn) +{ + if (scn == NULL) + return false; + + if (unlikely (scn->elf->state.elf.ehdr == NULL)) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + return false; + } + + if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + return false; + } + + return true; +} + +ElfW2(LIBELFBITS,Shdr) * +__elfw2(LIBELFBITS,getshdr_rdlock) (scn) + Elf_Scn *scn; +{ + ElfW2(LIBELFBITS,Shdr) *result; + + if (!scn_valid (scn)) + return NULL; + + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result == NULL) + { + rwlock_unlock (scn->elf->lock); + rwlock_wrlock (scn->elf->lock); + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result == NULL) + result = load_shdr_wrlock (scn); + } + + return result; +} + +ElfW2(LIBELFBITS,Shdr) * +__elfw2(LIBELFBITS,getshdr_wrlock) (scn) + Elf_Scn *scn; +{ + ElfW2(LIBELFBITS,Shdr) *result; + + if (!scn_valid (scn)) + return NULL; + + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result == NULL) + result = load_shdr_wrlock (scn); + + return result; +} + +ElfW2(LIBELFBITS,Shdr) * +elfw2(LIBELFBITS,getshdr) (scn) + Elf_Scn *scn; +{ + ElfW2(LIBELFBITS,Shdr) *result; + + if (!scn_valid (scn)) + return NULL; + + rwlock_rdlock (scn->elf->lock); + result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn); + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/elf32_newehdr.c b/libelf/elf32_newehdr.c new file mode 100644 index 0000000..4e20056 --- /dev/null +++ b/libelf/elf32_newehdr.c @@ -0,0 +1,113 @@ +/* Create new ELF header. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +ElfW2(LIBELFBITS,Ehdr) * +elfw2(LIBELFBITS,newehdr) (elf) + Elf *elf; +{ + ElfW2(LIBELFBITS,Ehdr) *result; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == 0) + elf->class = ELFW(ELFCLASS,LIBELFBITS); + else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + result = NULL; + goto out; + } + + /* Don't create an ELF header if one already exists. */ + if (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL) + { + /* We use the memory in the ELF descriptor. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr = + &elf->state.ELFW(elf,LIBELFBITS).ehdr_mem; + + /* We clear this memory. */ + memset (elf->state.ELFW(elf,LIBELFBITS).ehdr, '\0', + sizeof (ElfW2(LIBELFBITS,Ehdr))); + + /* Mark the ELF header has modified. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + + result = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,newehdr)) diff --git a/libelf/elf32_newphdr.c b/libelf/elf32_newphdr.c new file mode 100644 index 0000000..03ff100 --- /dev/null +++ b/libelf/elf32_newphdr.c @@ -0,0 +1,197 @@ +/* Create new ELF program header table. + Copyright (C) 1999-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +ElfW2(LIBELFBITS,Phdr) * +elfw2(LIBELFBITS,newphdr) (elf, count) + Elf *elf; + size_t count; +{ + ElfW2(LIBELFBITS,Phdr) *result; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + if (unlikely ((ElfW2(LIBELFBITS,Word)) count != count)) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == 0) + elf->class = ELFW(ELFCLASS,LIBELFBITS); + else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + result = NULL; + goto out; + } + + if (unlikely (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL)) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + result = NULL; + goto out; + } + + /* A COUNT of zero means remove existing table. */ + if (count == 0) + { + /* Free the old program header. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL) + { + if (elf->state.ELFW(elf,LIBELFBITS).phdr_flags & ELF_F_MALLOCED) + free (elf->state.ELFW(elf,LIBELFBITS).phdr); + + /* Set the pointer to NULL. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = NULL; + /* Set the `e_phnum' member to the new value. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = 0; + /* Also clear any old PN_XNUM extended value. */ + if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0) + elf->state.ELFW(elf,LIBELFBITS).scns.data[0] + .shdr.ELFW(e,LIBELFBITS)->sh_info = 0; + /* Also set the size. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize = + sizeof (ElfW2(LIBELFBITS,Phdr)); + + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY; + elf->flags |= ELF_F_DIRTY; + __libelf_seterrno (ELF_E_NOERROR); + } + + result = NULL; + } + else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count + || count == PN_XNUM + || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + { + /* Allocate a new program header with the appropriate number of + elements. */ + result = (ElfW2(LIBELFBITS,Phdr) *) + realloc (elf->state.ELFW(elf,LIBELFBITS).phdr, + count * sizeof (ElfW2(LIBELFBITS,Phdr))); + if (result == NULL) + __libelf_seterrno (ELF_E_NOMEM); + else + { + /* Now set the result. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = result; + if (count >= PN_XNUM) + { + /* We have to write COUNT into the zeroth section's sh_info. */ + Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; + if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt == 0) + { + assert (elf->state.ELFW(elf,LIBELFBITS).scns.max > 0); + elf->state.ELFW(elf,LIBELFBITS).scns.cnt = 1; + } + scn0->shdr.ELFW(e,LIBELFBITS)->sh_info = count; + scn0->shdr_flags |= ELF_F_DIRTY; + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = PN_XNUM; + } + else + /* Set the `e_phnum' member to the new value. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = count; + /* Clear the whole memory. */ + memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr))); + /* Also set the size. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize = + elf_typesize (LIBELFBITS, ELF_T_PHDR, 1); + /* Remember we allocated the array and mark the structure is + modified. */ + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= + ELF_F_DIRTY | ELF_F_MALLOCED; + /* We have to rewrite the entire file if the size of the + program header is changed. */ + elf->flags |= ELF_F_DIRTY; + } + } + else + { + /* We have the same number of entries. Just clear the array. */ + assert (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize + == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1)); + + /* Mark the structure as modified. */ + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY; + + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr))); + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,newphdr)) diff --git a/libelf/elf32_offscn.c b/libelf/elf32_offscn.c new file mode 100644 index 0000000..86eff8b --- /dev/null +++ b/libelf/elf32_offscn.c @@ -0,0 +1,121 @@ +/* Get section at specific index. + Copyright (C) 2005, 2008 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2005. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <stddef.h> +#include <stdlib.h> + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +Elf_Scn * +elfw2(LIBELFBITS,offscn) (elf, offset) + Elf *elf; + ElfW2(LIBELFBITS,Off) offset; +{ + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns; + + /* If we have not looked at section headers before, + we might need to read them in first. */ + if (runp->cnt > 0 + && unlikely (runp->data[0].shdr.ELFW(e,LIBELFBITS) == NULL) + && unlikely (elfw2(LIBELFBITS,getshdr) (&runp->data[0]) == NULL)) + return NULL; + + rwlock_rdlock (elf->lock); + + Elf_Scn *result = NULL; + + /* Find the section in the list. */ + while (1) + { + for (unsigned int i = 0; i < runp->cnt; ++i) + if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_offset == offset) + { + result = &runp->data[i]; + + /* If this section is empty, the following one has the same + sh_offset. We presume the caller is looking for a nonempty + section, so keep looking if this one is empty. */ + if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0) + goto out; + } + + runp = runp->next; + if (runp == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OFFSET); + break; + } + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,offscn)) diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c new file mode 100644 index 0000000..898cf1a --- /dev/null +++ b/libelf/elf32_updatefile.c @@ -0,0 +1,820 @@ +/* Write changed data structures. + Copyright (C) 2000-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <errno.h> +#include <libelf.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/param.h> + +#include <system.h> +#include "libelfP.h" + + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +static int +compare_sections (const void *a, const void *b) +{ + const Elf_Scn **scna = (const Elf_Scn **) a; + const Elf_Scn **scnb = (const Elf_Scn **) b; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset + < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset) + return -1; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset + > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset) + return 1; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_size + < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size) + return -1; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_size + > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size) + return 1; + + if ((*scna)->index < (*scnb)->index) + return -1; + + if ((*scna)->index > (*scnb)->index) + return 1; + + return 0; +} + + +/* Insert the sections in the list into the provided array and sort + them according to their start offsets. For sections with equal + start offsets, the size is used; for sections with equal start + offsets and sizes, the section index is used. Sorting by size + ensures that zero-length sections are processed first, which + is what we want since they do not advance our file writing position. */ +static void +sort_sections (Elf_Scn **scns, Elf_ScnList *list) +{ + Elf_Scn **scnp = scns; + do + for (size_t cnt = 0; cnt < list->cnt; ++cnt) + *scnp++ = &list->data[cnt]; + while ((list = list->next) != NULL); + + qsort (scns, scnp - scns, sizeof (*scns), compare_sections); +} + + +int +internal_function +__elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) +{ + bool previous_scn_changed = false; + + /* We need the ELF header several times. */ + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* Write out the ELF header. */ + if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY) + { + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Ehdr)) + == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)); + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#if EV_NUM != 2 + xfct_t fctp; + fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]; +#else +# undef fctp +# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR] +#endif + + /* Do the real work. */ + (*fctp) ((char *) elf->map_address + elf->start_offset, ehdr, + sizeof (ElfW2(LIBELFBITS,Ehdr)), 1); + } + else + memcpy (elf->map_address + elf->start_offset, ehdr, + sizeof (ElfW2(LIBELFBITS,Ehdr))); + + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY; + + /* We start writing sections after the ELF header only if there is + no program header. */ + previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL; + } + + size_t phnum; + if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0)) + return -1; + + /* Write out the program header table. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL + && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags) + & ELF_F_DIRTY)) + { + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Phdr)) + == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1)); + + /* Maybe the user wants a gap between the ELF header and the program + header. */ + if (ehdr->e_phoff > ehdr->e_ehsize) + memset (elf->map_address + elf->start_offset + ehdr->e_ehsize, + __libelf_fill_byte, ehdr->e_phoff - ehdr->e_ehsize); + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#if EV_NUM != 2 + xfct_t fctp; + fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]; +#else +# undef fctp +# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR] +#endif + + /* Do the real work. */ + (*fctp) (elf->map_address + elf->start_offset + ehdr->e_phoff, + elf->state.ELFW(elf,LIBELFBITS).phdr, + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1); + } + else + memcpy (elf->map_address + elf->start_offset + ehdr->e_phoff, + elf->state.ELFW(elf,LIBELFBITS).phdr, + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); + + elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY; + + /* We modified the program header. Maybe this created a gap so + we have to write fill bytes, if necessary. */ + previous_scn_changed = true; + } + + /* From now on we have to keep track of the last position to eventually + fill the gaps with the prescribed fill byte. */ + char *last_position = ((char *) elf->map_address + elf->start_offset + + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1), + ehdr->e_phoff) + + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum)); + + /* Write all the sections. Well, only those which are modified. */ + if (shnum > 0) + { + Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; + Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *)); + char *const shdr_start = ((char *) elf->map_address + elf->start_offset + + ehdr->e_shoff); + char *const shdr_end = shdr_start + ehdr->e_shnum * ehdr->e_shentsize; + +#if EV_NUM != 2 + xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]; +#else +# undef shdr_fctp +# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR] +#endif +#define shdr_dest ((ElfW2(LIBELFBITS,Shdr) *) shdr_start) + + /* Get all sections into the array and sort them. */ + sort_sections (scns, list); + + /* We possibly have to copy the section header data because moving + the sections might overwrite the data. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + + if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced + && (scn->shdr_flags & ELF_F_MALLOCED) == 0 + && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index]) + { + assert ((char *) elf->map_address + elf->start_offset + < (char *) scn->shdr.ELFW(e,LIBELFBITS)); + assert ((char *) scn->shdr.ELFW(e,LIBELFBITS) + < ((char *) elf->map_address + elf->start_offset + + elf->maximum_size)); + + void *p = alloca (sizeof (ElfW2(LIBELFBITS,Shdr))); + scn->shdr.ELFW(e,LIBELFBITS) + = memcpy (p, scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr))); + } + + /* If the file is mmaped and the original position of the + section in the file is lower than the new position we + need to save the section content since otherwise it is + overwritten before it can be copied. If there are + multiple data segments in the list only the first can be + from the file. */ + if (((char *) elf->map_address + elf->start_offset + <= (char *) scn->data_list.data.d.d_buf) + && ((char *) scn->data_list.data.d.d_buf + < ((char *) elf->map_address + elf->start_offset + + elf->maximum_size)) + && (((char *) elf->map_address + elf->start_offset + + scn->shdr.ELFW(e,LIBELFBITS)->sh_offset) + > (char *) scn->data_list.data.d.d_buf)) + { + void *p = malloc (scn->data_list.data.d.d_size); + if (p == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + scn->data_list.data.d.d_buf = scn->data_base + = memcpy (p, scn->data_list.data.d.d_buf, + scn->data_list.data.d.d_size); + } + } + + /* Iterate over all the section in the order in which they + appear in the output file. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + if (scn->index == 0) + { + /* The dummy section header entry. It should not be + possible to mark this "section" as dirty. */ + assert ((scn->flags & ELF_F_DIRTY) == 0); + continue; + } + + ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); + if (shdr->sh_type == SHT_NOBITS) + goto next; + + char *scn_start = ((char *) elf->map_address + + elf->start_offset + shdr->sh_offset); + Elf_Data_List *dl = &scn->data_list; + bool scn_changed = false; + + void fill_mmap (size_t offset) + { + size_t written = 0; + + if (last_position < shdr_start) + { + written = MIN (scn_start + offset - last_position, + shdr_start - last_position); + + memset (last_position, __libelf_fill_byte, written); + } + + if (last_position + written != scn_start + offset + && shdr_end < scn_start + offset) + { + char *fill_start = MAX (shdr_end, scn_start); + memset (fill_start, __libelf_fill_byte, + scn_start + offset - fill_start); + } + } + + if (scn->data_list_rear != NULL) + do + { + assert (dl->data.d.d_off >= 0); + assert ((GElf_Off) dl->data.d.d_off <= shdr->sh_size); + assert (dl->data.d.d_size <= (shdr->sh_size + - (GElf_Off) dl->data.d.d_off)); + + /* If there is a gap, fill it. */ + if (scn_start + dl->data.d.d_off > last_position + && (dl->data.d.d_off == 0 + || ((scn->flags | dl->flags | elf->flags) + & ELF_F_DIRTY) != 0)) + { + fill_mmap (dl->data.d.d_off); + last_position = scn_start + dl->data.d.d_off; + } + + if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY) + { + /* Let it go backward if the sections use a bogus + layout with overlaps. We'll overwrite the stupid + user's section data with the latest one, rather than + crashing. */ + + last_position = scn_start + dl->data.d.d_off; + + if (unlikely (change_bo)) + { +#if EV_NUM != 2 + xfct_t fctp; + fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]; +#else +# undef fctp +# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type] +#endif + + /* Do the real work. */ + (*fctp) (last_position, dl->data.d.d_buf, + dl->data.d.d_size, 1); + + last_position += dl->data.d.d_size; + } + else + last_position = mempcpy (last_position, + dl->data.d.d_buf, + dl->data.d.d_size); + + scn_changed = true; + } + else + last_position += dl->data.d.d_size; + + assert (scn_start + dl->data.d.d_off + dl->data.d.d_size + == last_position); + + dl->flags &= ~ELF_F_DIRTY; + + dl = dl->next; + } + while (dl != NULL); + else + { + /* If the previous section (or the ELF/program + header) changed we might have to fill the gap. */ + if (scn_start > last_position && previous_scn_changed) + fill_mmap (0); + + /* We have to trust the existing section header information. */ + last_position = scn_start + shdr->sh_size; + } + + + previous_scn_changed = scn_changed; + next: + scn->flags &= ~ELF_F_DIRTY; + } + + /* Fill the gap between last section and section header table if + necessary. */ + if ((elf->flags & ELF_F_DIRTY) + && last_position < ((char *) elf->map_address + elf->start_offset + + ehdr->e_shoff)) + memset (last_position, __libelf_fill_byte, + (char *) elf->map_address + elf->start_offset + ehdr->e_shoff + - last_position); + + /* Write the section header table entry if necessary. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + + if ((scn->shdr_flags | elf->flags) & ELF_F_DIRTY) + { + if (unlikely (change_bo)) + (*shdr_fctp) (&shdr_dest[scn->index], + scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr)), 1); + else + memcpy (&shdr_dest[scn->index], + scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr))); + + /* If we previously made a copy of the section header + entry we now have to adjust the pointer again so + point to new place in the mapping. */ + if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced + && (scn->shdr_flags & ELF_F_MALLOCED) == 0) + scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index]; + + scn->shdr_flags &= ~ELF_F_DIRTY; + } + } + } + + /* That was the last part. Clear the overall flag. */ + elf->flags &= ~ELF_F_DIRTY; + + /* Make sure the content hits the disk. */ + char *msync_start = ((char *) elf->map_address + + (elf->start_offset & ~(sysconf (_SC_PAGESIZE) - 1))); + char *msync_end = ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff + + ehdr->e_shentsize * shnum); + (void) msync (msync_start, msync_end - msync_start, MS_SYNC); + + return 0; +} + + +/* Size of the buffer we use to generate the blocks of fill bytes. */ +#define FILLBUFSIZE 4096 + +/* If we have to convert the section buffer contents we have to use + temporary buffer. Only buffers up to MAX_TMPBUF bytes are allocated + on the stack. */ +#define MAX_TMPBUF 32768 + + +/* Helper function to write out fill bytes. */ +static int +fill (int fd, off_t pos, size_t len, char *fillbuf, size_t *filledp) +{ + size_t filled = *filledp; + size_t fill_len = MIN (len, FILLBUFSIZE); + + if (unlikely (fill_len > filled) && filled < FILLBUFSIZE) + { + /* Initialize a few more bytes. */ + memset (fillbuf + filled, __libelf_fill_byte, fill_len - filled); + *filledp = filled = fill_len; + } + + do + { + /* This many bytes we want to write in this round. */ + size_t n = MIN (filled, len); + + if (unlikely ((size_t) pwrite_retry (fd, fillbuf, n, pos) != n)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + + pos += n; + len -= n; + } + while (len > 0); + + return 0; +} + + +int +internal_function +__elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) +{ + char fillbuf[FILLBUFSIZE]; + size_t filled = 0; + bool previous_scn_changed = false; + + /* We need the ELF header several times. */ + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* Write out the ELF header. */ + if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY) + { + ElfW2(LIBELFBITS,Ehdr) tmp_ehdr; + ElfW2(LIBELFBITS,Ehdr) *out_ehdr = ehdr; + + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Ehdr)) + == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)); + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#if EV_NUM != 2 + xfct_t fctp; + fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]; +#else +# undef fctp +# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR] +#endif + + /* Write the converted ELF header in a temporary buffer. */ + (*fctp) (&tmp_ehdr, ehdr, sizeof (ElfW2(LIBELFBITS,Ehdr)), 1); + + /* This is the buffer we want to write. */ + out_ehdr = &tmp_ehdr; + } + + /* Write out the ELF header. */ + if (unlikely (pwrite_retry (elf->fildes, out_ehdr, + sizeof (ElfW2(LIBELFBITS,Ehdr)), 0) + != sizeof (ElfW2(LIBELFBITS,Ehdr)))) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY; + + /* We start writing sections after the ELF header only if there is + no program header. */ + previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL; + } + + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Phdr)) + == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1)); + + size_t phnum; + if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0)) + return -1; + + /* Write out the program header table. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL + && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags) + & ELF_F_DIRTY)) + { + ElfW2(LIBELFBITS,Phdr) *tmp_phdr = NULL; + ElfW2(LIBELFBITS,Phdr) *out_phdr = elf->state.ELFW(elf,LIBELFBITS).phdr; + + /* Maybe the user wants a gap between the ELF header and the program + header. */ + if (ehdr->e_phoff > ehdr->e_ehsize + && unlikely (fill (elf->fildes, ehdr->e_ehsize, + ehdr->e_phoff - ehdr->e_ehsize, fillbuf, &filled) + != 0)) + return 1; + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#if EV_NUM != 2 + xfct_t fctp; + fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]; +#else +# undef fctp +# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR] +#endif + + /* Allocate sufficient memory. */ + tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *) + malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); + if (tmp_phdr == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return 1; + } + + /* Write the converted ELF header in a temporary buffer. */ + (*fctp) (tmp_phdr, elf->state.ELFW(elf,LIBELFBITS).phdr, + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1); + + /* This is the buffer we want to write. */ + out_phdr = tmp_phdr; + } + + /* Write out the ELF header. */ + size_t phdr_size = sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum; + if (unlikely ((size_t) pwrite_retry (elf->fildes, out_phdr, + phdr_size, ehdr->e_phoff) + != phdr_size)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + + /* This is a no-op we we have not allocated any memory. */ + free (tmp_phdr); + + elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY; + + /* We modified the program header. Maybe this created a gap so + we have to write fill bytes, if necessary. */ + previous_scn_changed = true; + } + + /* From now on we have to keep track of the last position to eventually + fill the gaps with the prescribed fill byte. */ + off_t last_offset; + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + last_offset = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); + else + last_offset = (ehdr->e_phoff + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); + + /* Write all the sections. Well, only those which are modified. */ + if (shnum > 0) + { + off_t shdr_offset = elf->start_offset + ehdr->e_shoff; +#if EV_NUM != 2 + xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]; +#else +# undef shdr_fctp +# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR] +#endif + + ElfW2(LIBELFBITS,Shdr) *shdr_data; + if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL) + shdr_data = (ElfW2(LIBELFBITS,Shdr) *) + alloca (shnum * sizeof (ElfW2(LIBELFBITS,Shdr))); + else + shdr_data = elf->state.ELFW(elf,LIBELFBITS).shdr; + int shdr_flags = elf->flags; + + /* Get all sections into the array and sort them. */ + Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; + Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *)); + sort_sections (scns, list); + + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + if (scn->index == 0) + { + /* The dummy section header entry. It should not be + possible to mark this "section" as dirty. */ + assert ((scn->flags & ELF_F_DIRTY) == 0); + goto next; + } + + ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); + if (shdr->sh_type == SHT_NOBITS) + goto next; + + off_t scn_start = elf->start_offset + shdr->sh_offset; + Elf_Data_List *dl = &scn->data_list; + bool scn_changed = false; + + if (scn->data_list_rear != NULL) + do + { + /* If there is a gap, fill it. */ + if (scn_start + dl->data.d.d_off > last_offset + && ((previous_scn_changed && dl->data.d.d_off == 0) + || ((scn->flags | dl->flags | elf->flags) + & ELF_F_DIRTY) != 0)) + { + if (unlikely (fill (elf->fildes, last_offset, + (scn_start + dl->data.d.d_off) + - last_offset, fillbuf, + &filled) != 0)) + return 1; + } + + if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY) + { + char tmpbuf[MAX_TMPBUF]; + void *buf = dl->data.d.d_buf; + + /* Let it go backward if the sections use a bogus + layout with overlaps. We'll overwrite the stupid + user's section data with the latest one, rather than + crashing. */ + + last_offset = scn_start + dl->data.d.d_off; + + if (unlikely (change_bo)) + { +#if EV_NUM != 2 + xfct_t fctp; + fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]; +#else +# undef fctp +# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type] +#endif + + buf = tmpbuf; + if (dl->data.d.d_size > MAX_TMPBUF) + { + buf = malloc (dl->data.d.d_size); + if (buf == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return 1; + } + } + + /* Do the real work. */ + (*fctp) (buf, dl->data.d.d_buf, dl->data.d.d_size, 1); + } + + ssize_t n = pwrite_retry (elf->fildes, buf, + dl->data.d.d_size, + last_offset); + if (unlikely ((size_t) n != dl->data.d.d_size)) + { + if (buf != dl->data.d.d_buf && buf != tmpbuf) + free (buf); + + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + + if (buf != dl->data.d.d_buf && buf != tmpbuf) + free (buf); + + scn_changed = true; + } + + last_offset += dl->data.d.d_size; + + dl->flags &= ~ELF_F_DIRTY; + + dl = dl->next; + } + while (dl != NULL); + else + { + /* If the previous section (or the ELF/program + header) changed we might have to fill the gap. */ + if (scn_start > last_offset && previous_scn_changed) + { + if (unlikely (fill (elf->fildes, last_offset, + scn_start - last_offset, fillbuf, + &filled) != 0)) + return 1; + } + + last_offset = scn_start + shdr->sh_size; + } + + previous_scn_changed = scn_changed; + next: + /* Collect the section header table information. */ + if (unlikely (change_bo)) + (*shdr_fctp) (&shdr_data[scn->index], + scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr)), 1); + else if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL) + memcpy (&shdr_data[scn->index], scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr))); + + shdr_flags |= scn->shdr_flags; + scn->shdr_flags &= ~ELF_F_DIRTY; + } + + /* Fill the gap between last section and section header table if + necessary. */ + if ((elf->flags & ELF_F_DIRTY) && last_offset < shdr_offset + && unlikely (fill (elf->fildes, last_offset, + shdr_offset - last_offset, + fillbuf, &filled) != 0)) + return 1; + + /* Write out the section header table. */ + if (shdr_flags & ELF_F_DIRTY + && unlikely ((size_t) pwrite_retry (elf->fildes, shdr_data, + sizeof (ElfW2(LIBELFBITS,Shdr)) + * shnum, shdr_offset) + != sizeof (ElfW2(LIBELFBITS,Shdr)) * shnum)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + } + + /* That was the last part. Clear the overall flag. */ + elf->flags &= ~ELF_F_DIRTY; + + return 0; +} diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c new file mode 100644 index 0000000..ca9a870 --- /dev/null +++ b/libelf/elf32_updatenull.c @@ -0,0 +1,438 @@ +/* Update data structures for changes. + Copyright (C) 2000-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <endian.h> +#include <libelf.h> +#include <stdbool.h> +#include <string.h> +#include <sys/param.h> + +#include "libelfP.h" +#include "elf-knowledge.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + + +static int +ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr, + size_t shnum, int *change_bop) +{ + /* Always write the magic bytes. */ + if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) + { + memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG); + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + + /* Always set the file class. */ + update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS), + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + + /* Set the data encoding if necessary. */ + if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE)) + { + ehdr->e_ident[EI_DATA] = + BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB; + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM)) + { + __libelf_seterrno (ELF_E_DATA_ENCODING); + return 1; + } + else + *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN + && ehdr->e_ident[EI_DATA] != ELFDATA2LSB) + || (BYTE_ORDER == BIG_ENDIAN + && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)); + + /* Unconditionally overwrite the ELF version. */ + update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT, + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + + if (unlikely (ehdr->e_version == EV_NONE) + || unlikely (ehdr->e_version >= EV_NUM)) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return 1; + } + + if (unlikely (shnum >= SHN_LORESERVE)) + { + update_if_changed (ehdr->e_shnum, 0, + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + } + else + update_if_changed (ehdr->e_shnum, shnum, + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + + if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1))) + { + ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + + return 0; +} + + +off_t +internal_function +__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) +{ + ElfW2(LIBELFBITS,Ehdr) *ehdr; + int changed = 0; + int ehdr_flags = 0; + + ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf); + + /* Set the default values. */ + if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0) + return -1; + + /* At least the ELF header is there. */ + off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); + + /* Set the program header position. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL + && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN + || ehdr->e_type == ET_CORE)) + (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf); + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL) + { + /* Only executables, shared objects, and core files have a program + header. */ + if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN + && unlikely (ehdr->e_type != ET_CORE)) + { + __libelf_seterrno (ELF_E_INVALID_PHDR); + return -1; + } + + size_t phnum; + if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0)) + return -1; + + if (elf->flags & ELF_F_LAYOUT) + { + /* The user is supposed to fill out e_phoff. Use it and + e_phnum to determine the maximum extend. */ + size = MAX ((size_t) size, + ehdr->e_phoff + + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum)); + } + else + { + update_if_changed (ehdr->e_phoff, + elf_typesize (LIBELFBITS, ELF_T_EHDR, 1), + ehdr_flags); + + /* We need no alignment here. */ + size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum); + } + } + + if (shnum > 0) + { + Elf_ScnList *list; + bool first = true; + + assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0); + + if (shnum >= SHN_LORESERVE) + { + /* We have to fill in the number of sections in the header + of the zeroth section. */ + Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; + + update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size, + shnum, scn0->shdr_flags); + } + + /* Go over all sections and find out how large they are. */ + list = &elf->state.ELFW(elf,LIBELFBITS).scns; + + /* Load the section headers if necessary. This loads the + headers for all sections. */ + if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL) + (void) __elfw2(LIBELFBITS,getshdr_wrlock) (&list->data[1]); + + do + { + for (size_t cnt = first == true; cnt < list->cnt; ++cnt) + { + Elf_Scn *scn = &list->data[cnt]; + ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); + off_t offset = 0; + + assert (shdr != NULL); + ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize; + ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1; + + /* Set the sh_entsize value if we can reliably detect it. */ + switch (shdr->sh_type) + { + case SHT_SYMTAB: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); + break; + case SHT_RELA: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1); + break; + case SHT_GROUP: + /* Only relocatable files can contain section groups. */ + if (ehdr->e_type != ET_REL) + { + __libelf_seterrno (ELF_E_GROUP_NOT_REL); + return -1; + } + /* FALLTHROUGH */ + case SHT_SYMTAB_SHNDX: + sh_entsize = elf_typesize (32, ELF_T_WORD, 1); + break; + case SHT_HASH: + sh_entsize = SH_ENTSIZE_HASH (ehdr); + break; + case SHT_DYNAMIC: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1); + break; + case SHT_REL: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1); + break; + case SHT_DYNSYM: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); + break; + case SHT_SUNW_move: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1); + break; + case SHT_SUNW_syminfo: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1); + break; + default: + break; + } + + /* If the section header contained the wrong entry size + correct it and mark the header as modified. */ + update_if_changed (shdr->sh_entsize, sh_entsize, + scn->shdr_flags); + + if (scn->data_read == 0 + && __libelf_set_rawdata_wrlock (scn) != 0) + /* Something went wrong. The error value is already set. */ + return -1; + + /* Iterate over all data blocks. */ + if (list->data[cnt].data_list_rear != NULL) + { + Elf_Data_List *dl = &scn->data_list; + + while (dl != NULL) + { + Elf_Data *data = &dl->data.d; + if (dl == &scn->data_list && data->d_buf == NULL + && scn->rawdata.d.d_buf != NULL) + data = &scn->rawdata.d; + + if (unlikely (data->d_version == EV_NONE) + || unlikely (data->d_version >= EV_NUM)) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return -1; + } + + if (unlikely (! powerof2 (data->d_align))) + { + __libelf_seterrno (ELF_E_INVALID_ALIGN); + return -1; + } + + sh_align = MAX (sh_align, data->d_align); + + if (elf->flags & ELF_F_LAYOUT) + { + /* The user specified the offset and the size. + All we have to do is check whether this block + fits in the size specified for the section. */ + if (unlikely ((GElf_Word) (data->d_off + + data->d_size) + > shdr->sh_size)) + { + __libelf_seterrno (ELF_E_SECTION_TOO_SMALL); + return -1; + } + } + else + { + /* Determine the padding. */ + offset = ((offset + data->d_align - 1) + & ~(data->d_align - 1)); + + update_if_changed (data->d_off, offset, changed); + + offset += data->d_size; + } + + /* Next data block. */ + dl = dl->next; + } + } + else + /* Get the size of the section from the raw data. If + none is available the value is zero. */ + offset += scn->rawdata.d.d_size; + + if (elf->flags & ELF_F_LAYOUT) + { + size = MAX ((GElf_Word) size, + shdr->sh_offset + + (shdr->sh_type != SHT_NOBITS + ? shdr->sh_size : 0)); + + /* The alignment must be a power of two. This is a + requirement from the ELF specification. Additionally + we test for the alignment of the section being large + enough for the largest alignment required by a data + block. */ + if (unlikely (! powerof2 (shdr->sh_addralign)) + || unlikely (shdr->sh_addralign < sh_align)) + { + __libelf_seterrno (ELF_E_INVALID_ALIGN); + return -1; + } + } + else + { + /* How much alignment do we need for this section. */ + update_if_changed (shdr->sh_addralign, sh_align, + scn->shdr_flags); + + size = (size + sh_align - 1) & ~(sh_align - 1); + int offset_changed = 0; + update_if_changed (shdr->sh_offset, (GElf_Word) size, + offset_changed); + changed |= offset_changed; + + if (offset_changed && scn->data_list_rear == NULL) + { + /* The position of the section in the file + changed. Create the section data list. */ + if (__elf_getdata_rdlock (scn, NULL) == NULL) + return -1; + } + + /* See whether the section size is correct. */ + update_if_changed (shdr->sh_size, (GElf_Word) offset, + changed); + + if (shdr->sh_type != SHT_NOBITS) + size += offset; + + scn->flags |= changed; + } + + /* Check that the section size is actually a multiple of + the entry size. */ + if (shdr->sh_entsize != 0 + && unlikely (shdr->sh_size % shdr->sh_entsize != 0) + && (elf->flags & ELF_F_PERMISSIVE) == 0) + { + __libelf_seterrno (ELF_E_INVALID_SHENTSIZE); + return -1; + } + } + + assert (list->next == NULL || list->cnt == list->max); + + first = false; + } + while ((list = list->next) != NULL); + + /* Store section information. */ + if (elf->flags & ELF_F_LAYOUT) + { + /* The user is supposed to fill out e_shoff. Use it and + e_shnum (or sh_size of the dummy, first section header) + to determine the maximum extend. */ + size = MAX ((GElf_Word) size, + (ehdr->e_shoff + + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum)))); + } + else + { + /* Align for section header table. + + Yes, we use `sizeof' and not `__alignof__' since we do not + want to be surprised by architectures with less strict + alignment rules. */ +#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off)) + size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1); + + update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags); + update_if_changed (ehdr->e_shentsize, + elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), + ehdr_flags); + + /* Account for the section header size. */ + size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum); + } + } + + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags; + + return size; +} diff --git a/libelf/elf32_xlatetof.c b/libelf/elf32_xlatetof.c new file mode 100644 index 0000000..dc686ec --- /dev/null +++ b/libelf/elf32_xlatetof.c @@ -0,0 +1,144 @@ +/* Convert from memory to file representation. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <endian.h> +#include <string.h> + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +Elf_Data * +elfw2(LIBELFBITS, xlatetof) (dest, src, encode) + Elf_Data *dest; + const Elf_Data *src; + unsigned int encode; +{ + /* First test whether the input data is really suitable for this + type. This means, whether there is an integer number of records. + Note that for this implementation the memory and file size of the + data types are identical. */ +#if EV_NUM != 2 + size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type]; +#else + size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type]; +#endif + + if (src->d_size % recsize != 0) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return NULL; + } + + /* Next see whether the converted data fits in the output buffer. */ + if (src->d_size > dest->d_size) + { + __libelf_seterrno (ELF_E_DEST_SIZE); + return NULL; + } + + /* Test the encode parameter. */ + if (encode != ELFDATA2LSB && encode != ELFDATA2MSB) + { + __libelf_seterrno (ELF_E_INVALID_ENCODING); + return NULL; + } + + /* Determine the translation function to use. + + At this point we make an assumption which is valid for all + existing implementations so far: the memory and file sizes are + the same. This has very important consequences: + a) The requirement that the source and destination buffer can + overlap can easily be fulfilled. + b) We need only one function to convert from and memory to file + and vice versa since the function only has to copy and/or + change the byte order. + */ + if ((__BYTE_ORDER == __LITTLE_ENDIAN && encode == ELFDATA2LSB) + || (__BYTE_ORDER == __BIG_ENDIAN && encode == ELFDATA2MSB)) + { + /* We simply have to copy since the byte order is the same. */ + if (src->d_buf != dest->d_buf) + memmove (dest->d_buf, src->d_buf, src->d_size); + } + else + { + xfct_t fctp; + + /* Get a pointer to the transformation functions. The `#ifdef' is + a small optimization since we don't anticipate another ELF + version and so would waste "precious" code. */ +#if EV_NUM != 2 + fctp = __elf_xfctstom[dest->d_version - 1][src->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type]; +#else + fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type]; +#endif + + /* Do the real work. */ + (*fctp) (dest->d_buf, src->d_buf, src->d_size, 1); + } + + /* Now set the real destination type and length since the operation was + successful. */ + dest->d_type = src->d_type; + dest->d_size = src->d_size; + + return dest; +} +INTDEF(elfw2(LIBELFBITS, xlatetof)) diff --git a/libelf/elf32_xlatetom.c b/libelf/elf32_xlatetom.c new file mode 100644 index 0000000..4f54df2 --- /dev/null +++ b/libelf/elf32_xlatetom.c @@ -0,0 +1,145 @@ +/* Convert from file to memory representation. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <endian.h> +#include <string.h> + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +Elf_Data * +elfw2(LIBELFBITS, xlatetom) (dest, src, encode) + Elf_Data *dest; + const Elf_Data *src; + unsigned int encode; +{ + /* First test whether the input data is really suitable for this + type. This means, whether there is an integer number of records. + Note that for this implementation the memory and file size of the + data types are identical. */ +#if EV_NUM != 2 + size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type]; +#else + size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type]; +#endif + + + if (src->d_size % recsize != 0) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return NULL; + } + + /* Next see whether the converted data fits in the output buffer. */ + if (src->d_size > dest->d_size) + { + __libelf_seterrno (ELF_E_DEST_SIZE); + return NULL; + } + + /* Test the encode parameter. */ + if (encode != ELFDATA2LSB && encode != ELFDATA2MSB) + { + __libelf_seterrno (ELF_E_INVALID_ENCODING); + return NULL; + } + + /* Determine the translation function to use. + + At this point we make an assumption which is valid for all + existing implementations so far: the memory and file sizes are + the same. This has very important consequences: + a) The requirement that the source and destination buffer can + overlap can easily be fulfilled. + b) We need only one function to convert from and memory to file + and vice versa since the function only has to copy and/or + change the byte order. + */ + if ((BYTE_ORDER == LITTLE_ENDIAN && encode == ELFDATA2LSB) + || (BYTE_ORDER == BIG_ENDIAN && encode == ELFDATA2MSB)) + { + /* We simply have to copy since the byte order is the same. */ + if (src->d_buf != dest->d_buf) + memmove (dest->d_buf, src->d_buf, src->d_size); + } + else + { + xfct_t fctp; + + /* Get a pointer to the transformation functions. The `#ifdef' is + a small optimization since we don't anticipate another ELF + version and so would waste "precious" code. */ +#if EV_NUM != 2 + fctp = __elf_xfctstom[src->d_version - 1][dest->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type]; +#else + fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type]; +#endif + + /* Do the real work. */ + (*fctp) (dest->d_buf, src->d_buf, src->d_size, 0); + } + + /* Now set the real destination type and length since the operation was + successful. */ + dest->d_type = src->d_type; + dest->d_size = src->d_size; + + return dest; +} +INTDEF(elfw2(LIBELFBITS, xlatetom)) diff --git a/libelf/elf64_checksum.c b/libelf/elf64_checksum.c new file mode 100644 index 0000000..000b66f --- /dev/null +++ b/libelf/elf64_checksum.c @@ -0,0 +1,52 @@ +/* Compute simple checksum from permanent parts of the ELF file. + Copyright (C) 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_checksum.c" diff --git a/libelf/elf64_fsize.c b/libelf/elf64_fsize.c new file mode 100644 index 0000000..2ee0512 --- /dev/null +++ b/libelf/elf64_fsize.c @@ -0,0 +1,52 @@ +/* Return the size of an object file type. + Copyright (C) 1998, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_fsize.c" diff --git a/libelf/elf64_getehdr.c b/libelf/elf64_getehdr.c new file mode 100644 index 0000000..c649679 --- /dev/null +++ b/libelf/elf64_getehdr.c @@ -0,0 +1,52 @@ +/* Return program header table. + Copyright (C) 1998, 1999, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_getehdr.c" diff --git a/libelf/elf64_getphdr.c b/libelf/elf64_getphdr.c new file mode 100644 index 0000000..5e2d0ea --- /dev/null +++ b/libelf/elf64_getphdr.c @@ -0,0 +1,52 @@ +/* Return program header table. + Copyright (C) 1998, 1999, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_getphdr.c" diff --git a/libelf/elf64_getshdr.c b/libelf/elf64_getshdr.c new file mode 100644 index 0000000..5b86dbe --- /dev/null +++ b/libelf/elf64_getshdr.c @@ -0,0 +1,52 @@ +/* Return section header. + Copyright (C) 1998, 1999, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_getshdr.c" diff --git a/libelf/elf64_newehdr.c b/libelf/elf64_newehdr.c new file mode 100644 index 0000000..eaea2b1 --- /dev/null +++ b/libelf/elf64_newehdr.c @@ -0,0 +1,52 @@ +/* Create new program header table. + Copyright (C) 1999, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_newehdr.c" diff --git a/libelf/elf64_newphdr.c b/libelf/elf64_newphdr.c new file mode 100644 index 0000000..91a4133 --- /dev/null +++ b/libelf/elf64_newphdr.c @@ -0,0 +1,52 @@ +/* Create new program header table. + Copyright (C) 1999, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_newphdr.c" diff --git a/libelf/elf64_offscn.c b/libelf/elf64_offscn.c new file mode 100644 index 0000000..6d31215 --- /dev/null +++ b/libelf/elf64_offscn.c @@ -0,0 +1,52 @@ +/* Return program header table. + Copyright (C) 2005 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2005. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_offscn.c" diff --git a/libelf/elf64_updatefile.c b/libelf/elf64_updatefile.c new file mode 100644 index 0000000..5502d18 --- /dev/null +++ b/libelf/elf64_updatefile.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_updatefile.c" diff --git a/libelf/elf64_updatenull.c b/libelf/elf64_updatenull.c new file mode 100644 index 0000000..6838fd8 --- /dev/null +++ b/libelf/elf64_updatenull.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_updatenull.c" diff --git a/libelf/elf64_xlatetof.c b/libelf/elf64_xlatetof.c new file mode 100644 index 0000000..2747ce0 --- /dev/null +++ b/libelf/elf64_xlatetof.c @@ -0,0 +1,52 @@ +/* Convert from memory to file representation. + Copyright (C) 1998, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_xlatetof.c" diff --git a/libelf/elf64_xlatetom.c b/libelf/elf64_xlatetom.c new file mode 100644 index 0000000..6fa6a02 --- /dev/null +++ b/libelf/elf64_xlatetom.c @@ -0,0 +1,52 @@ +/* Convert from file to memory representation. + Copyright (C) 1998, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#define LIBELFBITS 64 +#include "elf32_xlatetom.c" diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c new file mode 100644 index 0000000..e46add3 --- /dev/null +++ b/libelf/elf_begin.c @@ -0,0 +1,1110 @@ +/* Create descriptor for processing file. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stddef.h> +#include <string.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/param.h> +#include <sys/stat.h> + +#include <system.h> +#include "libelfP.h" +#include "common.h" + + +/* Create descriptor for archive in memory. */ +static inline Elf * +file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent) +{ + Elf *elf; + + /* Create a descriptor. */ + elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, + ELF_K_AR, 0); + if (elf != NULL) + { + /* We don't read all the symbol tables in advance. All this will + happen on demand. */ + elf->state.ar.offset = offset + SARMAG; + + elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name; + } + + return elf; +} + + +static size_t +get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, + size_t maxsize) +{ + size_t result; + union + { + Elf32_Ehdr *e32; + Elf64_Ehdr *e64; + void *p; + } ehdr; + union + { + Elf32_Ehdr e32; + Elf64_Ehdr e64; + } ehdr_mem; + bool is32 = e_ident[EI_CLASS] == ELFCLASS32; + + /* Make the ELF header available. */ + if (e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) e_ident + & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr)) + - 1)) == 0))) + ehdr.p = e_ident; + else + { + /* We already read the ELF header. We have to copy the header + since we possibly modify the data here and the caller + expects the memory it passes in to be preserved. */ + ehdr.p = &ehdr_mem; + + if (is32) + { + if (ALLOW_UNALIGNED) + { + ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum; + ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff; + } + else + memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (ehdr_mem.e32.e_shnum); + CONVERT (ehdr_mem.e32.e_shoff); + } + } + else + { + if (ALLOW_UNALIGNED) + { + ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum; + ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff; + } + else + memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (ehdr_mem.e64.e_shnum); + CONVERT (ehdr_mem.e64.e_shoff); + } + } + } + + if (is32) + { + /* Get the number of sections from the ELF header. */ + result = ehdr.e32->e_shnum; + + if (unlikely (result == 0) && ehdr.e32->e_shoff != 0) + { + if (ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize) + /* Cannot read the first section header. */ + return 0; + + if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) map_address + offset)) + & (__alignof__ (Elf32_Ehdr) - 1)) == 0)) + /* We can directly access the memory. */ + result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff + + offset))->sh_size; + else + { + Elf32_Word size; + + if (likely (map_address != NULL)) + /* gcc will optimize the memcpy to a simple memory + access while taking care of alignment issues. */ + memcpy (&size, &((Elf32_Shdr *) ((char *) map_address + + ehdr.e32->e_shoff + + offset))->sh_size, + sizeof (Elf32_Word)); + else + if (unlikely (pread_retry (fildes, &size, sizeof (Elf32_Word), + offset + ehdr.e32->e_shoff + + offsetof (Elf32_Shdr, sh_size)) + != sizeof (Elf32_Word))) + return (size_t) -1l; + + if (e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (size); + + result = size; + } + } + + /* If the section headers were truncated, pretend none were there. */ + if (ehdr.e32->e_shoff > maxsize + || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result) + result = 0; + } + else + { + /* Get the number of sections from the ELF header. */ + result = ehdr.e64->e_shnum; + + if (unlikely (result == 0) && ehdr.e64->e_shoff != 0) + { + if (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize) + /* Cannot read the first section header. */ + return 0; + + Elf64_Xword size; + if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) map_address + offset)) + & (__alignof__ (Elf64_Ehdr) - 1)) == 0)) + /* We can directly access the memory. */ + size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff + + offset))->sh_size; + else + { + if (likely (map_address != NULL)) + /* gcc will optimize the memcpy to a simple memory + access while taking care of alignment issues. */ + memcpy (&size, &((Elf64_Shdr *) ((char *) map_address + + ehdr.e64->e_shoff + + offset))->sh_size, + sizeof (Elf64_Xword)); + else + if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Word), + offset + ehdr.e64->e_shoff + + offsetof (Elf64_Shdr, sh_size)) + != sizeof (Elf64_Xword))) + return (size_t) -1l; + + if (e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (size); + } + + if (size > ~((GElf_Word) 0)) + /* Invalid value, it is too large. */ + return (size_t) -1l; + + result = size; + } + + /* If the section headers were truncated, pretend none were there. */ + if (ehdr.e64->e_shoff > maxsize + || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result) + result = 0; + } + + return result; +} + + +/* Create descriptor for ELF file in memory. */ +static Elf * +file_read_elf (int fildes, void *map_address, unsigned char *e_ident, + off_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent) +{ + /* Verify the binary is of the class we can handle. */ + if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32 + && e_ident[EI_CLASS] != ELFCLASS64) + /* We also can only handle two encodings. */ + || (e_ident[EI_DATA] != ELFDATA2LSB + && e_ident[EI_DATA] != ELFDATA2MSB))) + { + /* Cannot handle this. */ + __libelf_seterrno (ELF_E_INVALID_FILE); + return NULL; + } + + /* Determine the number of sections. */ + size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize); + if (scncnt == (size_t) -1l) + /* Could not determine the number of sections. */ + return NULL; + + /* We can now allocate the memory. Even if there are no section headers, + we allocate space for a zeroth section in case we need it later. */ + const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP) + ? 1 : 0); + Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, + ELF_K_ELF, scnmax * sizeof (Elf_Scn)); + if (elf == NULL) + /* Not enough memory. */ + return NULL; + + assert ((unsigned int) scncnt == scncnt); + assert (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)); + elf->state.elf32.scns.cnt = scncnt; + elf->state.elf32.scns.max = scnmax; + + /* Some more or less arbitrary value. */ + elf->state.elf.scnincr = 10; + + /* Make the class easily available. */ + elf->class = e_ident[EI_CLASS]; + + if (e_ident[EI_CLASS] == ELFCLASS32) + { + /* This pointer might not be directly usable if the alignment is + not sufficient for the architecture. */ + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset); + + /* This is a 32-bit binary. */ + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || ((((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0 + && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff) + & (__alignof__ (Elf32_Shdr) - 1)) == 0 + && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff) + & (__alignof__ (Elf32_Phdr) - 1)) == 0))) + { + /* We can use the mmapped memory. */ + elf->state.elf32.ehdr = ehdr; + elf->state.elf32.shdr + = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff); + + /* Don't precache the phdr pointer here. + elf32_getphdr will validate it against the size when asked. */ + + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf32.scns.data[cnt].index = cnt; + elf->state.elf32.scns.data[cnt].elf = elf; + elf->state.elf32.scns.data[cnt].shdr.e32 = + &elf->state.elf32.shdr[cnt]; + if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize) + && likely (maxsize - elf->state.elf32.shdr[cnt].sh_offset + <= elf->state.elf32.shdr[cnt].sh_size)) + elf->state.elf32.scns.data[cnt].rawdata_base = + elf->state.elf32.scns.data[cnt].data_base = + ((char *) map_address + offset + + elf->state.elf32.shdr[cnt].sh_offset); + elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns; + + /* If this is a section with an extended index add a + reference in the section which uses the extended + index. */ + if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX + && elf->state.elf32.shdr[cnt].sh_link < scncnt) + elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index + = cnt; + + /* Set the own shndx_index field in case it has not yet + been set. */ + if (elf->state.elf32.scns.data[cnt].shndx_index == 0) + elf->state.elf32.scns.data[cnt].shndx_index = -1; + } + } + else + { + /* Copy the ELF header. */ + elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident, + sizeof (Elf32_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (elf->state.elf32.ehdr_mem.e_type); + CONVERT (elf->state.elf32.ehdr_mem.e_machine); + CONVERT (elf->state.elf32.ehdr_mem.e_version); + CONVERT (elf->state.elf32.ehdr_mem.e_entry); + CONVERT (elf->state.elf32.ehdr_mem.e_phoff); + CONVERT (elf->state.elf32.ehdr_mem.e_shoff); + CONVERT (elf->state.elf32.ehdr_mem.e_flags); + CONVERT (elf->state.elf32.ehdr_mem.e_ehsize); + CONVERT (elf->state.elf32.ehdr_mem.e_phentsize); + CONVERT (elf->state.elf32.ehdr_mem.e_phnum); + CONVERT (elf->state.elf32.ehdr_mem.e_shentsize); + CONVERT (elf->state.elf32.ehdr_mem.e_shnum); + CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx); + } + + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf32.scns.data[cnt].index = cnt; + elf->state.elf32.scns.data[cnt].elf = elf; + elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns; + } + } + + /* So far only one block with sections. */ + elf->state.elf32.scns_last = &elf->state.elf32.scns; + } + else + { + /* This pointer might not be directly usable if the alignment is + not sufficient for the architecture. */ + Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset); + + /* This is a 64-bit binary. */ + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || ((((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0 + && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff) + & (__alignof__ (Elf64_Shdr) - 1)) == 0 + && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff) + & (__alignof__ (Elf64_Phdr) - 1)) == 0))) + { + /* We can use the mmapped memory. */ + elf->state.elf64.ehdr = ehdr; + elf->state.elf64.shdr + = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff); + + /* Don't precache the phdr pointer here. + elf64_getphdr will validate it against the size when asked. */ + + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf64.scns.data[cnt].index = cnt; + elf->state.elf64.scns.data[cnt].elf = elf; + elf->state.elf64.scns.data[cnt].shdr.e64 = + &elf->state.elf64.shdr[cnt]; + if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize) + && likely (maxsize - elf->state.elf64.shdr[cnt].sh_offset + <= elf->state.elf64.shdr[cnt].sh_size)) + elf->state.elf64.scns.data[cnt].rawdata_base = + elf->state.elf64.scns.data[cnt].data_base = + ((char *) map_address + offset + + elf->state.elf64.shdr[cnt].sh_offset); + elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns; + + /* If this is a section with an extended index add a + reference in the section which uses the extended + index. */ + if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX + && elf->state.elf64.shdr[cnt].sh_link < scncnt) + elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index + = cnt; + + /* Set the own shndx_index field in case it has not yet + been set. */ + if (elf->state.elf64.scns.data[cnt].shndx_index == 0) + elf->state.elf64.scns.data[cnt].shndx_index = -1; + } + } + else + { + /* Copy the ELF header. */ + elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident, + sizeof (Elf64_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (elf->state.elf64.ehdr_mem.e_type); + CONVERT (elf->state.elf64.ehdr_mem.e_machine); + CONVERT (elf->state.elf64.ehdr_mem.e_version); + CONVERT (elf->state.elf64.ehdr_mem.e_entry); + CONVERT (elf->state.elf64.ehdr_mem.e_phoff); + CONVERT (elf->state.elf64.ehdr_mem.e_shoff); + CONVERT (elf->state.elf64.ehdr_mem.e_flags); + CONVERT (elf->state.elf64.ehdr_mem.e_ehsize); + CONVERT (elf->state.elf64.ehdr_mem.e_phentsize); + CONVERT (elf->state.elf64.ehdr_mem.e_phnum); + CONVERT (elf->state.elf64.ehdr_mem.e_shentsize); + CONVERT (elf->state.elf64.ehdr_mem.e_shnum); + CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx); + } + + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf64.scns.data[cnt].index = cnt; + elf->state.elf64.scns.data[cnt].elf = elf; + elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns; + } + } + + /* So far only one block with sections. */ + elf->state.elf64.scns_last = &elf->state.elf64.scns; + } + + return elf; +} + + +Elf * +internal_function +__libelf_read_mmaped_file (int fildes, void *map_address, off_t offset, + size_t maxsize, Elf_Cmd cmd, Elf *parent) +{ + /* We have to find out what kind of file this is. We handle ELF + files and archives. To find out what we have we must look at the + header. The header for an ELF file is EI_NIDENT bytes in size, + the header for an archive file SARMAG bytes long. */ + unsigned char *e_ident = (unsigned char *) map_address + offset; + + /* See what kind of object we have here. */ + Elf_Kind kind = determine_kind (e_ident, maxsize); + + switch (kind) + { + case ELF_K_ELF: + return file_read_elf (fildes, map_address, e_ident, offset, maxsize, + cmd, parent); + + case ELF_K_AR: + return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent); + + default: + break; + } + + /* This case is easy. Since we cannot do anything with this file + create a dummy descriptor. */ + return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, + ELF_K_NONE, 0); +} + + +static Elf * +read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd, + Elf *parent) +{ + /* We have to find out what kind of file this is. We handle ELF + files and archives. To find out what we have we must read the + header. The identification header for an ELF file is EI_NIDENT + bytes in size, but we read the whole ELF header since we will + need it anyway later. For archives the header in SARMAG bytes + long. Read the maximum of these numbers. + + XXX We have to change this for the extended `ar' format some day. + + Use a union to ensure alignment. We might later access the + memory as a ElfXX_Ehdr. */ + union + { + Elf64_Ehdr ehdr; + unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)]; + } mem; + + /* Read the head of the file. */ + ssize_t nread = pread_retry (fildes, mem.header, + MIN (MAX (sizeof (Elf64_Ehdr), SARMAG), + maxsize), + offset); + if (unlikely (nread == -1)) + /* We cannot even read the head of the file. Maybe FILDES is associated + with an unseekable device. This is nothing we can handle. */ + return NULL; + + /* See what kind of object we have here. */ + Elf_Kind kind = determine_kind (mem.header, nread); + + switch (kind) + { + case ELF_K_AR: + return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent); + + case ELF_K_ELF: + /* Make sure at least the ELF header is contained in the file. */ + if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32 + ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))) + return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd, + parent); + /* FALLTHROUGH */ + + default: + break; + } + + /* This case is easy. Since we cannot do anything with this file + create a dummy descriptor. */ + return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent, + ELF_K_NONE, 0); +} + + +/* Open a file for reading. If possible we will try to mmap() the file. */ +static struct Elf * +read_file (int fildes, off_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent) +{ + void *map_address = NULL; + int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP + || cmd == ELF_C_WRITE_MMAP + || cmd == ELF_C_READ_MMAP_PRIVATE); + +#if _MUDFLAP + /* Mudflap doesn't grok that our mmap'd data is ok. */ + use_mmap = 0; +#endif + + if (use_mmap) + { + if (parent == NULL) + { + if (maxsize == ~((size_t) 0)) + { + /* We don't know in the moment how large the file is. + Determine it now. */ + struct stat st; + + if (fstat (fildes, &st) == 0 + && (sizeof (size_t) >= sizeof (st.st_size) + || st.st_size <= ~((size_t) 0))) + maxsize = (size_t) st.st_size; + } + + /* We try to map the file ourself. */ + map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP + ? PROT_READ + : PROT_READ|PROT_WRITE), + cmd == ELF_C_READ_MMAP_PRIVATE + || cmd == ELF_C_READ_MMAP + ? MAP_PRIVATE : MAP_SHARED, + fildes, offset); + + if (map_address == MAP_FAILED) + map_address = NULL; + } + else + { + /* The parent is already loaded. Use it. */ + assert (maxsize != ~((size_t) 0)); + + map_address = parent->map_address; + } + } + + /* If we have the file in memory optimize the access. */ + if (map_address != NULL) + { + assert (map_address != MAP_FAILED); + + struct Elf *result = __libelf_read_mmaped_file (fildes, map_address, + offset, maxsize, cmd, + parent); + + /* If something went wrong during the initialization unmap the + memory if we mmaped here. */ + if (result == NULL + && (parent == NULL + || parent->map_address != map_address)) + munmap (map_address, maxsize); + else if (parent == NULL) + /* Remember that we mmap()ed the memory. */ + result->flags |= ELF_F_MMAPPED; + + return result; + } + + /* Otherwise we have to do it the hard way. We read as much as necessary + from the file whenever we need information which is not available. */ + return read_unmmaped_file (fildes, offset, maxsize, cmd, parent); +} + + +/* Find the entry with the long names for the content of this archive. */ +static const char * +read_long_names (Elf *elf) +{ + off_t offset = SARMAG; /* This is the first entry. */ + struct ar_hdr hdrm; + struct ar_hdr *hdr; + char *newp; + size_t len; + + while (1) + { + if (elf->map_address != NULL) + { + if (offset + sizeof (struct ar_hdr) > elf->maximum_size) + return NULL; + + /* The data is mapped. */ + hdr = (struct ar_hdr *) (elf->map_address + offset); + } + else + { + /* Read the header from the file. */ + if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm), + elf->start_offset + offset) + != sizeof (hdrm))) + return NULL; + + hdr = &hdrm; + } + + len = atol (hdr->ar_size); + + if (memcmp (hdr->ar_name, "// ", 16) == 0) + break; + + offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l); + } + + /* Due to the stupid format of the long name table entry (which are not + NUL terminted) we have to provide an appropriate representation anyhow. + Therefore we always make a copy which has the appropriate form. */ + newp = (char *) malloc (len); + if (newp != NULL) + { + char *runp; + + if (elf->map_address != NULL) + /* Simply copy it over. */ + elf->state.ar.long_names = (char *) memcpy (newp, + elf->map_address + offset + + sizeof (struct ar_hdr), + len); + else + { + if (unlikely ((size_t) pread_retry (elf->fildes, newp, len, + elf->start_offset + offset + + sizeof (struct ar_hdr)) + != len)) + { + /* We were not able to read all data. */ + free (newp); + elf->state.ar.long_names = NULL; + return NULL; + } + elf->state.ar.long_names = newp; + } + + elf->state.ar.long_names_len = len; + + /* Now NUL-terminate the strings. */ + runp = newp; + while (1) + { + runp = (char *) memchr (runp, '/', newp + len - runp); + if (runp == NULL) + /* This was the last entry. */ + break; + + /* NUL-terminate the string. */ + *runp = '\0'; + + /* Skip the NUL byte and the \012. */ + runp += 2; + + /* A sanity check. Somebody might have generated invalid + archive. */ + if (runp >= newp + len) + break; + } + } + + return newp; +} + + +/* Read the next archive header. */ +int +internal_function +__libelf_next_arhdr_wrlock (elf) + Elf *elf; +{ + struct ar_hdr *ar_hdr; + Elf_Arhdr *elf_ar_hdr; + + if (elf->map_address != NULL) + { + /* See whether this entry is in the file. */ + if (unlikely (elf->state.ar.offset + sizeof (struct ar_hdr) + > elf->start_offset + elf->maximum_size)) + { + /* This record is not anymore in the file. */ + __libelf_seterrno (ELF_E_RANGE); + return -1; + } + ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset); + } + else + { + ar_hdr = &elf->state.ar.ar_hdr; + + if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr), + elf->state.ar.offset) + != sizeof (struct ar_hdr))) + { + /* Something went wrong while reading the file. */ + __libelf_seterrno (ELF_E_RANGE); + return -1; + } + } + + /* One little consistency check. */ + if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0)) + { + /* This is no valid archive. */ + __libelf_seterrno (ELF_E_ARCHIVE_FMAG); + return -1; + } + + /* Copy the raw name over to a NUL terminated buffer. */ + *((char *) __mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0'; + + elf_ar_hdr = &elf->state.ar.elf_ar_hdr; + + /* Now convert the `struct ar_hdr' into `Elf_Arhdr'. + Determine whether this is a special entry. */ + if (ar_hdr->ar_name[0] == '/') + { + if (ar_hdr->ar_name[1] == ' ' + && memcmp (ar_hdr->ar_name, "/ ", 16) == 0) + /* This is the index. */ + elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2); + else if (ar_hdr->ar_name[1] == '/' + && memcmp (ar_hdr->ar_name, "// ", 16) == 0) + /* This is the array with the long names. */ + elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3); + else if (likely (isdigit (ar_hdr->ar_name[1]))) + { + size_t offset; + + /* This is a long name. First we have to read the long name + table, if this hasn't happened already. */ + if (unlikely (elf->state.ar.long_names == NULL + && read_long_names (elf) == NULL)) + { + /* No long name table although it is reference. The archive is + broken. */ + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + + offset = atol (ar_hdr->ar_name + 1); + if (unlikely (offset >= elf->state.ar.long_names_len)) + { + /* The index in the long name table is larger than the table. */ + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + elf_ar_hdr->ar_name = elf->state.ar.long_names + offset; + } + else + { + /* This is none of the known special entries. */ + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + } + else + { + char *endp; + + /* It is a normal entry. Copy over the name. */ + endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name, + '/', 16); + if (endp != NULL) + endp[-1] = '\0'; + else + { + /* In the old BSD style of archive, there is no / terminator. + Instead, there is space padding at the end of the name. */ + size_t i = 15; + do + elf->state.ar.ar_name[i] = '\0'; + while (i > 0 && elf->state.ar.ar_name[--i] == ' '); + } + + elf_ar_hdr->ar_name = elf->state.ar.ar_name; + } + + if (unlikely (ar_hdr->ar_size[0] == ' ')) + /* Something is really wrong. We cannot live without a size for + the member since it will not be possible to find the next + archive member. */ + { + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + + /* Since there are no specialized functions to convert ASCII to + time_t, uid_t, gid_t, mode_t, and off_t we use either atol or + atoll depending on the size of the types. We are also prepared + for the case where the whole field in the `struct ar_hdr' is + filled in which case we cannot simply use atol/l but instead have + to create a temporary copy. */ + +#define INT_FIELD(FIELD) \ + do \ + { \ + char buf[sizeof (ar_hdr->FIELD) + 1]; \ + const char *string = ar_hdr->FIELD; \ + if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \ + { \ + *((char *) __mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \ + = '\0'; \ + string = buf; \ + } \ + if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \ + elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string); \ + else \ + elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string); \ + } \ + while (0) + + INT_FIELD (ar_date); + INT_FIELD (ar_uid); + INT_FIELD (ar_gid); + INT_FIELD (ar_mode); + INT_FIELD (ar_size); + + return 0; +} + + +/* We were asked to return a clone of an existing descriptor. This + function must be called with the lock on the parent descriptor + being held. */ +static Elf * +dup_elf (int fildes, Elf_Cmd cmd, Elf *ref) +{ + struct Elf *result; + + if (fildes == -1) + /* Allow the user to pass -1 as the file descriptor for the new file. */ + fildes = ref->fildes; + /* The file descriptor better should be the same. If it was disconnected + already (using `elf_cntl') we do not test it. */ + else if (unlikely (ref->fildes != -1 && fildes != ref->fildes)) + { + __libelf_seterrno (ELF_E_FD_MISMATCH); + return NULL; + } + + /* The mode must allow reading. I.e., a descriptor creating with a + command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is + not allowed. */ + if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP + && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP + && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP + && ref->cmd != ELF_C_READ_MMAP_PRIVATE)) + { + __libelf_seterrno (ELF_E_INVALID_OP); + return NULL; + } + + /* Now it is time to distinguish between reading normal files and + archives. Normal files can easily be handled be incrementing the + reference counter and return the same descriptor. */ + if (ref->kind != ELF_K_AR) + { + ++ref->ref_count; + return ref; + } + + /* This is an archive. We must create a descriptor for the archive + member the internal pointer of the archive file desriptor is + pointing to. First read the header of the next member if this + has not happened already. */ + if (ref->state.ar.elf_ar_hdr.ar_name == NULL + && __libelf_next_arhdr_wrlock (ref) != 0) + /* Something went wrong. Maybe there is no member left. */ + return NULL; + + /* We have all the information we need about the next archive member. + Now create a descriptor for it. */ + result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr), + ref->state.ar.elf_ar_hdr.ar_size, cmd, ref); + + /* Enlist this new descriptor in the list of children. */ + if (result != NULL) + { + result->next = ref->state.ar.children; + ref->state.ar.children = result; + } + + return result; +} + + +/* Return desriptor for empty file ready for writing. */ +static struct Elf * +write_file (int fd, Elf_Cmd cmd) +{ + /* We simply create an empty `Elf' structure. */ +#define NSCNSALLOC 10 + Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF, + NSCNSALLOC * sizeof (Elf_Scn)); + + if (result != NULL) + { + /* We have to write to the file in any case. */ + result->flags = ELF_F_DIRTY; + + /* Some more or less arbitrary value. */ + result->state.elf.scnincr = NSCNSALLOC; + + /* We have allocated room for some sections. */ + assert (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)); + result->state.elf.scns_last = &result->state.elf32.scns; + result->state.elf32.scns.max = NSCNSALLOC; + } + + return result; +} + + +/* Return a descriptor for the file belonging to FILDES. */ +Elf * +elf_begin (fildes, cmd, ref) + int fildes; + Elf_Cmd cmd; + Elf *ref; +{ + Elf *retval; + + if (unlikely (! __libelf_version_initialized)) + { + /* Version wasn't set so far. */ + __libelf_seterrno (ELF_E_NO_VERSION); + return NULL; + } + + if (ref != NULL) + /* Make sure the descriptor is not suddenly going away. */ + rwlock_rdlock (ref->lock); + else if (unlikely (fcntl (fildes, F_GETFL) == -1 && errno == EBADF)) + { + /* We cannot do anything productive without a file descriptor. */ + __libelf_seterrno (ELF_E_INVALID_FILE); + return NULL; + } + + Elf *lock_dup_elf () + { + /* We need wrlock to dup an archive. */ + if (ref->kind == ELF_K_AR) + { + rwlock_unlock (ref->lock); + rwlock_wrlock (ref->lock); + } + + /* Duplicate the descriptor. */ + return dup_elf (fildes, cmd, ref); + } + + switch (cmd) + { + case ELF_C_NULL: + /* We simply return a NULL pointer. */ + retval = NULL; + break; + + case ELF_C_READ_MMAP_PRIVATE: + /* If we have a reference it must also be opened this way. */ + if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE)) + { + __libelf_seterrno (ELF_E_INVALID_CMD); + retval = NULL; + break; + } + /* FALLTHROUGH */ + + case ELF_C_READ: + case ELF_C_READ_MMAP: + if (ref != NULL) + retval = lock_dup_elf (); + else + /* Create descriptor for existing file. */ + retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL); + break; + + case ELF_C_RDWR: + case ELF_C_RDWR_MMAP: + /* If we have a REF object it must also be opened using this + command. */ + if (ref != NULL) + { + if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP + && ref->cmd != ELF_C_WRITE + && ref->cmd != ELF_C_WRITE_MMAP)) + { + /* This is not ok. REF must also be opened for writing. */ + __libelf_seterrno (ELF_E_INVALID_CMD); + retval = NULL; + } + else + retval = lock_dup_elf (); + } + else + /* Create descriptor for existing file. */ + retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL); + break; + + case ELF_C_WRITE: + case ELF_C_WRITE_MMAP: + /* We ignore REF and prepare a descriptor to write a new file. */ + retval = write_file (fildes, cmd); + break; + + default: + __libelf_seterrno (ELF_E_INVALID_CMD); + retval = NULL; + break; + } + + /* Release the lock. */ + if (ref != NULL) + rwlock_unlock (ref->lock); + + return retval; +} +INTDEF(elf_begin) diff --git a/libelf/elf_clone.c b/libelf/elf_clone.c new file mode 100644 index 0000000..8b699fa --- /dev/null +++ b/libelf/elf_clone.c @@ -0,0 +1,102 @@ +/* Create clone of a given descriptor. + Copyright (C) 2003, 2004 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <stddef.h> +#include "libelfP.h" +#include "common.h" + + +Elf * +elf_clone (Elf *elf, Elf_Cmd cmd) +{ + Elf *retval = NULL; + + if (elf == NULL) + /* Some earlier mistake. */ + return NULL; + + /* Make sure the descriptor is not suddenly going away. */ + rwlock_rdlock (elf->lock); + + if (cmd != ELF_C_EMPTY) + // XXX TODO handle ELF_C_READ/WRITE etc + goto out; + + retval = allocate_elf (elf->fildes, elf->map_address, elf->start_offset, + elf->maximum_size, elf->cmd, elf->parent, elf->kind, + elf->state.elf32.scns.max * sizeof (Elf_Scn)); + if (retval != NULL) + { + /* We have to write to the file in any case. */ + retval->flags = ELF_F_DIRTY; + + /* Some more or less arbitrary value. */ + retval->state.elf.scnincr = 10; + + /* We have allocated room for some sections. */ + assert (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)); + retval->state.elf.scns_last = &retval->state.elf32.scns; + retval->state.elf32.scns.max = elf->state.elf32.scns.max; + + retval->class = elf->class; + } + + /* Release the lock. */ + out: + rwlock_unlock (elf->lock); + + return retval; +} diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c new file mode 100644 index 0000000..fd5b47b --- /dev/null +++ b/libelf/elf_cntl.c @@ -0,0 +1,104 @@ +/* Control an ELF file desrciptor. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <unistd.h> + +#include "libelfP.h" + + +int +elf_cntl (elf, cmd) + Elf *elf; + Elf_Cmd cmd; +{ + int result = 0; + + if (elf == NULL) + return -1; + + if (elf->fildes == -1) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_wrlock (elf->lock); + + switch (cmd) + { + case ELF_C_FDREAD: + /* If not all of the file is in the memory read it now. */ + if (elf->map_address == NULL && __libelf_readall (elf) == NULL) + { + /* We were not able to read everything. */ + result = -1; + break; + } + /* FALLTHROUGH */ + + case ELF_C_FDDONE: + /* Mark the file descriptor as not usable. */ + elf->fildes = -1; + break; + + default: + __libelf_seterrno (ELF_E_INVALID_CMD); + result = -1; + break; + } + + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_end.c b/libelf/elf_end.c new file mode 100644 index 0000000..5112eae --- /dev/null +++ b/libelf/elf_end.c @@ -0,0 +1,252 @@ +/* Free resources associated with Elf descriptor. + Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <stddef.h> +#include <stdlib.h> +#include <sys/mman.h> + +#include "libelfP.h" + + +int +elf_end (elf) + Elf *elf; +{ + Elf *parent; + + if (elf == NULL) + /* This is allowed and is a no-op. */ + return 0; + + /* Make sure we are alone. */ + rwlock_wrlock (elf->lock); + + if (elf->ref_count != 0 && --elf->ref_count != 0) + { + /* Not yet the last activation. */ + int result = elf->ref_count; + rwlock_unlock (elf->lock); + return result; + } + + if (elf->kind == ELF_K_AR) + { + /* We cannot remove the descriptor now since we still have some + descriptors which depend on it. But we can free the archive + symbol table since this is only available via the archive ELF + descriptor. The long name table cannot be freed yet since + the archive headers for the ELF files in the archive point + into this array. */ + if (elf->state.ar.ar_sym != (Elf_Arsym *) -1l) + free (elf->state.ar.ar_sym); + elf->state.ar.ar_sym = NULL; + + if (elf->state.ar.children != NULL) + return 0; + } + + /* Remove this structure from the children list. */ + parent = elf->parent; + if (parent != NULL) + { + /* This is tricky. Lock must be acquire from the father to + the child but here we already have the child lock. We + solve this problem by giving free the child lock. The + state of REF_COUNT==0 is handled all over the library, so + this should be ok. */ + rwlock_unlock (elf->lock); + rwlock_rdlock (parent->lock); + rwlock_wrlock (elf->lock); + + if (parent->state.ar.children == elf) + parent->state.ar.children = elf->next; + else + { + struct Elf *child = parent->state.ar.children; + + while (child->next != elf) + child = child->next; + + child->next = elf->next; + } + + rwlock_unlock (parent->lock); + } + + /* This was the last activation. Free all resources. */ + switch (elf->kind) + { + case ELF_K_AR: + if (elf->state.ar.long_names != NULL) + free (elf->state.ar.long_names); + break; + + case ELF_K_ELF: + { + Elf_Data_Chunk *rawchunks + = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.rawchunks) + == offsetof (struct Elf, state.elf64.rawchunks)) + ? elf->state.elf32.rawchunks + : elf->state.elf64.rawchunks); + while (rawchunks != NULL) + { + Elf_Data_Chunk *next = rawchunks->next; + if (rawchunks->dummy_scn.flags & ELF_F_MALLOCED) + free (rawchunks->data.d.d_buf); + free (rawchunks); + rawchunks = next; + } + + Elf_ScnList *list = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns + : &elf->state.elf64.scns); + + do + { + /* Free all separately allocated section headers. */ + size_t cnt = list->max; + + while (cnt-- > 0) + { + /* These pointers can be NULL; it's safe to use + 'free' since it will check for this. */ + Elf_Scn *scn = &list->data[cnt]; + Elf_Data_List *runp; + + if ((scn->shdr_flags & ELF_F_MALLOCED) != 0) + /* It doesn't matter which pointer. */ + free (scn->shdr.e32); + + /* If the file has the same byte order and the + architecture doesn't require overly stringent + alignment the raw data buffer is the same as the + one used for presenting to the caller. */ + if (scn->data_base != scn->rawdata_base) + free (scn->data_base); + + /* The section data is allocated if we couldn't mmap + the file. */ + if (elf->map_address == NULL) + free (scn->rawdata_base); + + /* Free the list of data buffers for the section. + We don't free the buffers themselves since this + is the users job. */ + runp = scn->data_list.next; + while (runp != NULL) + { + Elf_Data_List *oldp = runp; + runp = runp->next; + if ((oldp->flags & ELF_F_MALLOCED) != 0) + free (oldp); + } + } + + /* Free the memory for the array. */ + Elf_ScnList *oldp = list; + list = list->next; + assert (list == NULL || oldp->cnt == oldp->max); + if (oldp != (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns + : &elf->state.elf64.scns)) + free (oldp); + } + while (list != NULL); + } + + /* Free the section header. */ + if (elf->state.elf.shdr_malloced != 0) + free (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.shdr) + == offsetof (struct Elf, state.elf64.shdr)) + ? (void *) elf->state.elf32.shdr + : (void *) elf->state.elf64.shdr); + + /* Free the program header. */ + if ((elf->state.elf.phdr_flags & ELF_F_MALLOCED) != 0) + free (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.phdr) + == offsetof (struct Elf, state.elf64.phdr)) + ? (void *) elf->state.elf32.phdr + : (void *) elf->state.elf64.phdr); + break; + + default: + break; + } + + if (elf->map_address != NULL && parent == NULL) + { + /* The file was read or mapped for this descriptor. */ + if ((elf->flags & ELF_F_MALLOCED) != 0) + free (elf->map_address); + else if ((elf->flags & ELF_F_MMAPPED) != 0) + munmap (elf->map_address, elf->maximum_size); + } + + rwlock_fini (elf->lock); + + /* Finally the descriptor itself. */ + free (elf); + + return (parent != NULL && parent->ref_count == 0 + ? INTUSE(elf_end) (parent) : 0); +} +INTDEF(elf_end) diff --git a/libelf/elf_error.c b/libelf/elf_error.c new file mode 100644 index 0000000..7f7504e --- /dev/null +++ b/libelf/elf_error.c @@ -0,0 +1,330 @@ +/* Error handling in libelf. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <libintl.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include "libelfP.h" + + +/* The error number. */ +static __thread int global_error; + + +int +elf_errno (void) +{ + int result = global_error; + global_error = ELF_E_NOERROR; + return result; +} + + +/* Return the appropriate message for the error. */ +static const char msgstr[] = +{ +#define ELF_E_NOERROR_IDX 0 + N_("no error") + "\0" +#define ELF_E_UNKNOWN_ERROR_IDX (ELF_E_NOERROR_IDX + sizeof "no error") + N_("unknown error") + "\0" +#define ELF_E_UNKNOWN_VERSION_IDX \ + (ELF_E_UNKNOWN_ERROR_IDX + sizeof "unknown error") + N_("unknown version") + "\0" +#define ELF_E_UNKNOWN_TYPE_IDX \ + (ELF_E_UNKNOWN_VERSION_IDX + sizeof "unknown version") + N_("unknown type") + "\0" +#define ELF_E_INVALID_HANDLE_IDX \ + (ELF_E_UNKNOWN_TYPE_IDX + sizeof "unknown type") + N_("invalid `Elf' handle") + "\0" +#define ELF_E_SOURCE_SIZE_IDX \ + (ELF_E_INVALID_HANDLE_IDX + sizeof "invalid `Elf' handle") + N_("invalid size of source operand") + "\0" +#define ELF_E_DEST_SIZE_IDX \ + (ELF_E_SOURCE_SIZE_IDX + sizeof "invalid size of source operand") + N_("invalid size of destination operand") + "\0" +#define ELF_E_INVALID_ENCODING_IDX \ + (ELF_E_DEST_SIZE_IDX + sizeof "invalid size of destination operand") + N_("invalid encoding") + "\0" +#define ELF_E_NOMEM_IDX \ + (ELF_E_INVALID_ENCODING_IDX + sizeof "invalid encoding") + N_("out of memory") + "\0" +#define ELF_E_INVALID_FILE_IDX \ + (ELF_E_NOMEM_IDX + sizeof "out of memory") + N_("invalid file descriptor") + "\0" +#define ELF_E_INVALID_OP_IDX \ + (ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor") + N_("invalid operation") + "\0" +#define ELF_E_NO_VERSION_IDX \ + (ELF_E_INVALID_OP_IDX + sizeof "invalid operation") + N_("ELF version not set") + "\0" +#define ELF_E_INVALID_CMD_IDX \ + (ELF_E_NO_VERSION_IDX + sizeof "ELF version not set") + N_("invalid command") + "\0" +#define ELF_E_RANGE_IDX \ + (ELF_E_INVALID_CMD_IDX + sizeof "invalid command") + N_("offset out of range") + "\0" +#define ELF_E_ARCHIVE_FMAG_IDX \ + (ELF_E_RANGE_IDX + sizeof "offset out of range") + N_("invalid fmag field in archive header") + "\0" +#define ELF_E_INVALID_ARCHIVE_IDX \ + (ELF_E_ARCHIVE_FMAG_IDX + sizeof "invalid fmag field in archive header") + N_("invalid archive file") + "\0" +#define ELF_E_NO_ARCHIVE_IDX \ + (ELF_E_INVALID_ARCHIVE_IDX + sizeof "invalid archive file") + N_("descriptor is not for an archive") + "\0" +#define ELF_E_NO_INDEX_IDX \ + (ELF_E_NO_ARCHIVE_IDX + sizeof "descriptor is not for an archive") + N_("no index available") + "\0" +#define ELF_E_READ_ERROR_IDX \ + (ELF_E_NO_INDEX_IDX + sizeof "no index available") + N_("cannot read data from file") + "\0" +#define ELF_E_WRITE_ERROR_IDX \ + (ELF_E_READ_ERROR_IDX + sizeof "cannot read data from file") + N_("cannot write data to file") + "\0" +#define ELF_E_INVALID_CLASS_IDX \ + (ELF_E_WRITE_ERROR_IDX + sizeof "cannot write data to file") + N_("invalid binary class") + "\0" +#define ELF_E_INVALID_INDEX_IDX \ + (ELF_E_INVALID_CLASS_IDX + sizeof "invalid binary class") + N_("invalid section index") + "\0" +#define ELF_E_INVALID_OPERAND_IDX \ + (ELF_E_INVALID_INDEX_IDX + sizeof "invalid section index") + N_("invalid operand") + "\0" +#define ELF_E_INVALID_SECTION_IDX \ + (ELF_E_INVALID_OPERAND_IDX + sizeof "invalid operand") + N_("invalid section") + "\0" +#define ELF_E_INVALID_COMMAND_IDX \ + (ELF_E_INVALID_SECTION_IDX + sizeof "invalid section") + N_("invalid command") + "\0" +#define ELF_E_WRONG_ORDER_EHDR_IDX \ + (ELF_E_INVALID_COMMAND_IDX + sizeof "invalid command") + N_("executable header not created first") + "\0" +#define ELF_E_FD_DISABLED_IDX \ + (ELF_E_WRONG_ORDER_EHDR_IDX + sizeof "executable header not created first") + N_("file descriptor disabled") + "\0" +#define ELF_E_FD_MISMATCH_IDX \ + (ELF_E_FD_DISABLED_IDX + sizeof "file descriptor disabled") + N_("archive/member file descriptor mismatch") + "\0" +#define ELF_E_OFFSET_RANGE_IDX \ + (ELF_E_FD_MISMATCH_IDX + sizeof "archive/member file descriptor mismatch") + N_("offset out of range") + "\0" +#define ELF_E_NOT_NUL_SECTION_IDX \ + (ELF_E_OFFSET_RANGE_IDX + sizeof "offset out of range") + N_("cannot manipulate null section") + "\0" +#define ELF_E_DATA_MISMATCH_IDX \ + (ELF_E_NOT_NUL_SECTION_IDX + sizeof "cannot manipulate null section") + N_("data/scn mismatch") + "\0" +#define ELF_E_INVALID_SECTION_HEADER_IDX \ + (ELF_E_DATA_MISMATCH_IDX + sizeof "data/scn mismatch") + N_("invalid section header") + "\0" +#define ELF_E_INVALID_DATA_IDX \ + (ELF_E_INVALID_SECTION_HEADER_IDX + sizeof "invalid section header") + N_("invalid data") + "\0" +#define ELF_E_DATA_ENCODING_IDX \ + (ELF_E_INVALID_DATA_IDX + sizeof "invalid data") + N_("unknown data encoding") + "\0" +#define ELF_E_SECTION_TOO_SMALL_IDX \ + (ELF_E_DATA_ENCODING_IDX + sizeof "unknown data encoding") + N_("section `sh_size' too small for data") + "\0" +#define ELF_E_INVALID_ALIGN_IDX \ + (ELF_E_SECTION_TOO_SMALL_IDX + sizeof "section `sh_size' too small for data") + N_("invalid section alignment") + "\0" +#define ELF_E_INVALID_SHENTSIZE_IDX \ + (ELF_E_INVALID_ALIGN_IDX + sizeof "invalid section alignment") + N_("invalid section entry size") + "\0" +#define ELF_E_UPDATE_RO_IDX \ + (ELF_E_INVALID_SHENTSIZE_IDX + sizeof "invalid section entry size") + N_("update() for write on read-only file") + "\0" +#define ELF_E_NOFILE_IDX \ + (ELF_E_UPDATE_RO_IDX + sizeof "update() for write on read-only file") + N_("no such file") + "\0" +#define ELF_E_GROUP_NOT_REL_IDX \ + (ELF_E_NOFILE_IDX + sizeof "no such file") + N_("only relocatable files can contain section groups") + "\0" +#define ELF_E_INVALID_PHDR_IDX \ + (ELF_E_GROUP_NOT_REL_IDX \ + + sizeof "only relocatable files can contain section groups") + N_("program header only allowed in executables, shared objects, and \ +core files") + "\0" +#define ELF_E_NO_PHDR_IDX \ + (ELF_E_INVALID_PHDR_IDX \ + + sizeof "program header only allowed in executables, shared objects, and \ +core files") + N_("file has no program header") + "\0" +#define ELF_E_INVALID_OFFSET_IDX \ + (ELF_E_NO_PHDR_IDX \ + + sizeof "file has no program header") + N_("invalid offset") +}; + + +static const uint_fast16_t msgidx[ELF_E_NUM] = +{ + [ELF_E_NOERROR] = ELF_E_NOERROR_IDX, + [ELF_E_UNKNOWN_ERROR] = ELF_E_UNKNOWN_ERROR_IDX, + [ELF_E_UNKNOWN_VERSION] = ELF_E_UNKNOWN_VERSION_IDX, + [ELF_E_UNKNOWN_TYPE] = ELF_E_UNKNOWN_TYPE_IDX, + [ELF_E_INVALID_HANDLE] = ELF_E_INVALID_HANDLE_IDX, + [ELF_E_SOURCE_SIZE] = ELF_E_SOURCE_SIZE_IDX, + [ELF_E_DEST_SIZE] = ELF_E_DEST_SIZE_IDX, + [ELF_E_INVALID_ENCODING] = ELF_E_INVALID_ENCODING_IDX, + [ELF_E_NOMEM] = ELF_E_NOMEM_IDX, + [ELF_E_INVALID_FILE] = ELF_E_INVALID_FILE_IDX, + [ELF_E_INVALID_OP] = ELF_E_INVALID_OP_IDX, + [ELF_E_NO_VERSION] = ELF_E_NO_VERSION_IDX, + [ELF_E_INVALID_CMD] = ELF_E_INVALID_CMD_IDX, + [ELF_E_RANGE] = ELF_E_RANGE_IDX, + [ELF_E_ARCHIVE_FMAG] = ELF_E_ARCHIVE_FMAG_IDX, + [ELF_E_INVALID_ARCHIVE] = ELF_E_INVALID_ARCHIVE_IDX, + [ELF_E_NO_ARCHIVE] = ELF_E_NO_ARCHIVE_IDX, + [ELF_E_NO_INDEX] = ELF_E_NO_INDEX_IDX, + [ELF_E_READ_ERROR] = ELF_E_READ_ERROR_IDX, + [ELF_E_WRITE_ERROR] = ELF_E_WRITE_ERROR_IDX, + [ELF_E_INVALID_CLASS] = ELF_E_INVALID_CLASS_IDX, + [ELF_E_INVALID_INDEX] = ELF_E_INVALID_INDEX_IDX, + [ELF_E_INVALID_OPERAND] = ELF_E_INVALID_OPERAND_IDX, + [ELF_E_INVALID_SECTION] = ELF_E_INVALID_SECTION_IDX, + [ELF_E_INVALID_COMMAND] = ELF_E_INVALID_COMMAND_IDX, + [ELF_E_WRONG_ORDER_EHDR] = ELF_E_WRONG_ORDER_EHDR_IDX, + [ELF_E_FD_DISABLED] = ELF_E_FD_DISABLED_IDX, + [ELF_E_FD_MISMATCH] = ELF_E_FD_MISMATCH_IDX, + [ELF_E_OFFSET_RANGE] = ELF_E_OFFSET_RANGE_IDX, + [ELF_E_NOT_NUL_SECTION] = ELF_E_NOT_NUL_SECTION_IDX, + [ELF_E_DATA_MISMATCH] = ELF_E_DATA_MISMATCH_IDX, + [ELF_E_INVALID_SECTION_HEADER] = ELF_E_INVALID_SECTION_HEADER_IDX, + [ELF_E_INVALID_DATA] = ELF_E_INVALID_DATA_IDX, + [ELF_E_DATA_ENCODING] = ELF_E_DATA_ENCODING_IDX, + [ELF_E_SECTION_TOO_SMALL] = ELF_E_SECTION_TOO_SMALL_IDX, + [ELF_E_INVALID_ALIGN] = ELF_E_INVALID_ALIGN_IDX, + [ELF_E_INVALID_SHENTSIZE] = ELF_E_INVALID_SHENTSIZE_IDX, + [ELF_E_UPDATE_RO] = ELF_E_UPDATE_RO_IDX, + [ELF_E_NOFILE] = ELF_E_NOFILE_IDX, + [ELF_E_GROUP_NOT_REL] = ELF_E_GROUP_NOT_REL_IDX, + [ELF_E_INVALID_PHDR] = ELF_E_INVALID_PHDR_IDX, + [ELF_E_NO_PHDR] = ELF_E_NO_PHDR_IDX, + [ELF_E_INVALID_OFFSET] = ELF_E_INVALID_OFFSET_IDX +}; +#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0]))) + + +void +__libelf_seterrno (value) + int value; +{ + global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR; +} + + +const char * +elf_errmsg (error) + int error; +{ + int last_error = global_error; + + if (error == 0) + { + assert (msgidx[last_error] < sizeof (msgstr)); + return last_error != 0 ? _(msgstr + msgidx[last_error]) : NULL; + } + else if (error < -1 || error >= nmsgidx) + return _(msgstr + ELF_E_UNKNOWN_ERROR_IDX); + + assert (msgidx[error == -1 ? last_error : error] < sizeof (msgstr)); + return _(msgstr + msgidx[error == -1 ? last_error : error]); +} diff --git a/libelf/elf_fill.c b/libelf/elf_fill.c new file mode 100644 index 0000000..ae69951 --- /dev/null +++ b/libelf/elf_fill.c @@ -0,0 +1,68 @@ +/* Set fill byte used when constructing ELF objects. + Copyright (C) 1998, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> + +#include "libelfP.h" + + +int __libelf_fill_byte; + + +void +elf_fill (fill) + int fill; +{ + __libelf_fill_byte = fill; +} diff --git a/libelf/elf_flagdata.c b/libelf/elf_flagdata.c new file mode 100644 index 0000000..a2cbdd9 --- /dev/null +++ b/libelf/elf_flagdata.c @@ -0,0 +1,92 @@ +/* Manipulate ELF data flag. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +unsigned int +elf_flagdata (data, cmd, flags) + Elf_Data *data; + Elf_Cmd cmd; + unsigned int flags; +{ + Elf_Data_Scn *data_scn; + unsigned int result; + + if (data == NULL) + return 0; + + data_scn = (Elf_Data_Scn *) data; + + if (data_scn == NULL || unlikely (data_scn->s->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (data_scn->s->flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (data_scn->s->flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagehdr.c b/libelf/elf_flagehdr.c new file mode 100644 index 0000000..499cf1d --- /dev/null +++ b/libelf/elf_flagehdr.c @@ -0,0 +1,89 @@ +/* Manipulate ELF header flags. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +unsigned int +elf_flagehdr (elf, cmd, flags) + Elf *elf; + Elf_Cmd cmd; + unsigned int flags; +{ + unsigned int result; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (elf->state.elf.ehdr_flags |= (flags & ELF_F_DIRTY)); + else if (cmd == ELF_C_CLR) + result = (elf->state.elf.ehdr_flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagelf.c b/libelf/elf_flagelf.c new file mode 100644 index 0000000..4ea4500 --- /dev/null +++ b/libelf/elf_flagelf.c @@ -0,0 +1,91 @@ +/* Manipulate ELF file flags. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +unsigned int +elf_flagelf (elf, cmd, flags) + Elf *elf; + Elf_Cmd cmd; + unsigned int flags; +{ + unsigned int result; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (elf->flags + |= (flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE))); + else if (likely (cmd == ELF_C_CLR)) + result = (elf->flags + &= ~(flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE))); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagphdr.c b/libelf/elf_flagphdr.c new file mode 100644 index 0000000..de1bccf --- /dev/null +++ b/libelf/elf_flagphdr.c @@ -0,0 +1,89 @@ +/* Manipulate ELF program header flags. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +unsigned int +elf_flagphdr (elf, cmd, flags) + Elf *elf; + Elf_Cmd cmd; + unsigned int flags; +{ + unsigned int result; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (elf->state.elf.phdr_flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (elf->state.elf.phdr_flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagscn.c b/libelf/elf_flagscn.c new file mode 100644 index 0000000..f4dba95 --- /dev/null +++ b/libelf/elf_flagscn.c @@ -0,0 +1,89 @@ +/* Manipulate ELF section flags. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +unsigned int +elf_flagscn (scn, cmd, flags) + Elf_Scn *scn; + Elf_Cmd cmd; + unsigned int flags; +{ + unsigned int result; + + if (scn == NULL) + return 0; + + if (unlikely (scn->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (scn->flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (scn->flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagshdr.c b/libelf/elf_flagshdr.c new file mode 100644 index 0000000..de645bb --- /dev/null +++ b/libelf/elf_flagshdr.c @@ -0,0 +1,89 @@ +/* Manipulate ELF section header flags. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +unsigned int +elf_flagshdr (scn, cmd, flags) + Elf_Scn *scn; + Elf_Cmd cmd; + unsigned int flags; +{ + unsigned int result; + + if (scn == NULL) + return 0; + + if (unlikely (scn->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (scn->shdr_flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (scn->shdr_flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_getarhdr.c b/libelf/elf_getarhdr.c new file mode 100644 index 0000000..61e4e0a --- /dev/null +++ b/libelf/elf_getarhdr.c @@ -0,0 +1,95 @@ +/* Read header of next archive member. + Copyright (C) 1998, 1999, 2000, 2002, 2008 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +Elf_Arhdr * +elf_getarhdr (elf) + Elf *elf; +{ + if (elf == NULL) + return NULL; + + Elf *parent = elf->parent; + + /* Calling this function is not ok for any file type but archives. */ + if (parent == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OP); + return NULL; + } + + /* Make sure we have read the archive header. */ + if (parent->state.ar.elf_ar_hdr.ar_name == NULL + && __libelf_next_arhdr_wrlock (parent) != 0) + { + rwlock_wrlock (parent->lock); + int st = __libelf_next_arhdr_wrlock (parent); + rwlock_unlock (parent->lock); + + if (st != 0) + /* Something went wrong. Maybe there is no member left. */ + return NULL; + } + + /* We can be sure the parent is an archive. */ + assert (parent->kind == ELF_K_AR); + + return &parent->state.ar.elf_ar_hdr; +} diff --git a/libelf/elf_getaroff.c b/libelf/elf_getaroff.c new file mode 100644 index 0000000..8dea061 --- /dev/null +++ b/libelf/elf_getaroff.c @@ -0,0 +1,75 @@ +/* Return offset in archive for current file ELF. + Copyright (C) 2005, 2008 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2005. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +off_t +elf_getaroff (elf) + Elf *elf; +{ + /* Be gratious, the specs demand it. */ + if (elf == NULL || elf->parent == NULL) + return ELF_C_NULL; + + /* We can be sure the parent is an archive. */ + Elf *parent = elf->parent; + assert (parent->kind == ELF_K_AR); + + return elf->start_offset - sizeof (struct ar_hdr) - parent->start_offset; +} diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c new file mode 100644 index 0000000..e6ecaad --- /dev/null +++ b/libelf/elf_getarsym.c @@ -0,0 +1,278 @@ +/* Return symbol table of archive. + Copyright (C) 1998, 1999, 2000, 2002, 2005 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <byteswap.h> +#include <endian.h> +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <system.h> +#include <dl-hash.h> +#include "libelfP.h" + + +Elf_Arsym * +elf_getarsym (elf, ptr) + Elf *elf; + size_t *ptr; +{ + if (elf->kind != ELF_K_AR) + { + /* This is no archive. */ + __libelf_seterrno (ELF_E_NO_ARCHIVE); + return NULL; + } + + if (ptr != NULL) + /* In case of an error or when we know the value store the expected + value now. Doing this allows us easier exits in an error case. */ + *ptr = elf->state.ar.ar_sym_num; + + if (elf->state.ar.ar_sym == (Elf_Arsym *) -1l) + { + /* There is no index. */ + __libelf_seterrno (ELF_E_NO_INDEX); + return NULL; + } + + Elf_Arsym *result = elf->state.ar.ar_sym; + if (result == NULL) + { + /* We have not yet read the index. */ + rwlock_wrlock (elf->lock); + + /* In case we find no index remember this for the next call. */ + elf->state.ar.ar_sym = (Elf_Arsym *) -1l; + + struct ar_hdr *index_hdr; + if (elf->map_address == NULL) + { + /* We must read index from the file. */ + assert (elf->fildes != -1); + if (pread_retry (elf->fildes, &elf->state.ar.ar_hdr, + sizeof (struct ar_hdr), elf->start_offset + SARMAG) + != sizeof (struct ar_hdr)) + { + /* It is not possible to read the index. Maybe it does not + exist. */ + __libelf_seterrno (ELF_E_READ_ERROR); + goto out; + } + + index_hdr = &elf->state.ar.ar_hdr; + } + else + { + if (SARMAG + sizeof (struct ar_hdr) > elf->maximum_size) + { + /* There is no room for the full archive. */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + index_hdr = (struct ar_hdr *) (elf->map_address + + elf->start_offset + SARMAG); + } + + /* Now test whether this really is an archive. */ + if (memcmp (index_hdr->ar_fmag, ARFMAG, 2) != 0) + { + /* Invalid magic bytes. */ + __libelf_seterrno (ELF_E_ARCHIVE_FMAG); + goto out; + } + + /* Now test whether this is the index. It is denoted by the + name being "/ ". + XXX This is not entirely true. There are some more forms. + Which of them shall we handle? */ + if (memcmp (index_hdr->ar_name, "/ ", 16) != 0) + { + /* If the index is not the first entry, there is no index. + + XXX Is this true? */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + /* We have an archive. The first word in there is the number of + entries in the table. */ + uint32_t n; + if (elf->map_address == NULL) + { + if (pread_retry (elf->fildes, &n, sizeof (n), + elf->start_offset + SARMAG + sizeof (struct ar_hdr)) + != sizeof (n)) + { + /* Cannot read the number of entries. */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + } + else + n = *(uint32_t *) (elf->map_address + elf->start_offset + + SARMAG + sizeof (struct ar_hdr)); + + if (__BYTE_ORDER == __LITTLE_ENDIAN) + n = bswap_32 (n); + + /* Now we can perform some first tests on whether all the data + needed for the index is available. */ + char tmpbuf[17]; + memcpy (tmpbuf, index_hdr->ar_size, 10); + tmpbuf[10] = '\0'; + size_t index_size = atol (tmpbuf); + + if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size + || n * sizeof (uint32_t) > index_size) + { + /* This index table cannot be right since it does not fit into + the file. */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + /* Now we can allocate the arrays needed to store the index. */ + size_t ar_sym_len = (n + 1) * sizeof (Elf_Arsym); + elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len); + if (elf->state.ar.ar_sym != NULL) + { + uint32_t *file_data; + char *str_data; + + if (elf->map_address == NULL) + { + file_data = (uint32_t *) alloca (n * sizeof (uint32_t)); + + ar_sym_len += index_size - n * sizeof (uint32_t); + Elf_Arsym *newp = (Elf_Arsym *) realloc (elf->state.ar.ar_sym, + ar_sym_len); + if (newp == NULL) + { + free (elf->state.ar.ar_sym); + elf->state.ar.ar_sym = NULL; + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ar.ar_sym = newp; + + char *new_str = (char *) (elf->state.ar.ar_sym + n + 1); + + /* Now read the data from the file. */ + if ((size_t) pread_retry (elf->fildes, file_data, + n * sizeof (uint32_t), + elf->start_offset + SARMAG + + sizeof (struct ar_hdr) + + sizeof (uint32_t)) + != n * sizeof (uint32_t) + || ((size_t) pread_retry (elf->fildes, new_str, + index_size - n * sizeof (uint32_t), + elf->start_offset + + SARMAG + sizeof (struct ar_hdr) + + (n + 1) * sizeof (uint32_t)) + != index_size - n * sizeof (uint32_t))) + { + /* We were not able to read the data. */ + free (elf->state.ar.ar_sym); + elf->state.ar.ar_sym = NULL; + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + str_data = (char *) new_str; + } + else + { + file_data = (uint32_t *) (elf->map_address + elf->start_offset + + SARMAG + sizeof (struct ar_hdr) + + sizeof (uint32_t)); + str_data = (char *) &file_data[n]; + } + + /* Now we can build the data structure. */ + Elf_Arsym *arsym = elf->state.ar.ar_sym; + for (size_t cnt = 0; cnt < n; ++cnt) + { + arsym[cnt].as_name = str_data; + if (__BYTE_ORDER == __LITTLE_ENDIAN) + arsym[cnt].as_off = bswap_32 (file_data[cnt]); + else + arsym[cnt].as_off = file_data[cnt]; + arsym[cnt].as_hash = _dl_elf_hash (str_data); + str_data = rawmemchr (str_data, '\0') + 1; + } + /* At the end a special entry. */ + arsym[n].as_name = NULL; + arsym[n].as_off = 0; + arsym[n].as_hash = ~0UL; + + /* Tell the caller how many entries we have. */ + elf->state.ar.ar_sym_num = n + 1; + } + + result = elf->state.ar.ar_sym; + + out: + rwlock_unlock (elf->lock); + } + + if (ptr != NULL) + *ptr = elf->state.ar.ar_sym_num; + + return result; +} diff --git a/libelf/elf_getbase.c b/libelf/elf_getbase.c new file mode 100644 index 0000000..2b6cf85 --- /dev/null +++ b/libelf/elf_getbase.c @@ -0,0 +1,66 @@ +/* Return offset of first byte for the object. + Copyright (C) 1998, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +off_t +elf_getbase (elf) + Elf *elf; +{ + return elf == NULL ? (off_t) -1 : elf->start_offset; +} diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c new file mode 100644 index 0000000..5a718f8 --- /dev/null +++ b/libelf/elf_getdata.c @@ -0,0 +1,506 @@ +/* Return the next data element from the section after possibly converting it. + Copyright (C) 1998-2005, 2006, 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <stddef.h> +#include <string.h> +#include <unistd.h> + +#include "libelfP.h" +#include <system.h> +#include "common.h" +#include "elf-knowledge.h" + + +#define TYPEIDX(Sh_Type) \ + (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM \ + ? Sh_Type \ + : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW \ + ? SHT_NUM + Sh_Type - SHT_GNU_HASH \ + : 0)) + +/* Associate section types with libelf types. */ +static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] = + { + [EV_CURRENT - 1] = + { + [SHT_SYMTAB] = ELF_T_SYM, + [SHT_RELA] = ELF_T_RELA, + [SHT_HASH] = ELF_T_WORD, + [SHT_DYNAMIC] = ELF_T_DYN, + [SHT_REL] = ELF_T_REL, + [SHT_DYNSYM] = ELF_T_SYM, + [SHT_INIT_ARRAY] = ELF_T_ADDR, + [SHT_FINI_ARRAY] = ELF_T_ADDR, + [SHT_PREINIT_ARRAY] = ELF_T_ADDR, + [SHT_GROUP] = ELF_T_WORD, + [SHT_SYMTAB_SHNDX] = ELF_T_WORD, + [SHT_NOTE] = ELF_T_NHDR, + [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF, + [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED, + [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF, + [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO, + [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE, + [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB, + [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH, + } + }; + +#if !ALLOW_UNALIGNED +/* Associate libelf types with their internal alignment requirements. */ +const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] = + { +# define TYPE_ALIGNS(Bits) \ + { \ + [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)), \ + [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)), \ + [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)), \ + [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)), \ + [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)), \ + [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)), \ + [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)), \ + [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)), \ + [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)), \ + [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)), \ + [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)), \ + [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)), \ + [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)), \ + [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)), \ + [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \ + } + [EV_CURRENT - 1] = + { + [ELFCLASS32 - 1] = TYPE_ALIGNS (32), + [ELFCLASS64 - 1] = TYPE_ALIGNS (64), + } +# undef TYPE_ALIGNS + }; +#endif + + +/* Convert the data in the current section. */ +static void +convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass, + int data, size_t size, Elf_Type type) +{ + const size_t align = __libelf_type_align (eclass, type); + + if (data == MY_ELFDATA) + { + if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0) + /* No need to copy, we can use the raw data. */ + scn->data_base = scn->rawdata_base; + else + { + scn->data_base = (char *) malloc (size); + if (scn->data_base == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return; + } + + /* The copy will be appropriately aligned for direct access. */ + memcpy (scn->data_base, scn->rawdata_base, size); + } + } + else + { + xfct_t fp; + + scn->data_base = (char *) malloc (size); + if (scn->data_base == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return; + } + + /* Get the conversion function. */ +#if EV_NUM != 2 + fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type]; +#else + fp = __elf_xfctstom[0][0][eclass - 1][type]; +#endif + + fp (scn->data_base, scn->rawdata_base, size, 0); + } + + scn->data_list.data.d.d_buf = scn->data_base; + scn->data_list.data.d.d_size = size; + scn->data_list.data.d.d_type = type; + scn->data_list.data.d.d_off = scn->rawdata.d.d_off; + scn->data_list.data.d.d_align = scn->rawdata.d.d_align; + scn->data_list.data.d.d_version = scn->rawdata.d.d_version; + + scn->data_list.data.s = scn; +} + + +/* Store the information for the raw data in the `rawdata' element. */ +int +internal_function +__libelf_set_rawdata_wrlock (Elf_Scn *scn) +{ + size_t offset; + size_t size; + size_t align; + int type; + Elf *elf = scn->elf; + + if (elf->class == ELFCLASS32) + { + Elf32_Shdr *shdr + = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn); + + if (shdr == NULL) + /* Something went terribly wrong. */ + return 1; + + offset = shdr->sh_offset; + size = shdr->sh_size; + type = shdr->sh_type; + align = shdr->sh_addralign; + } + else + { + Elf64_Shdr *shdr + = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn); + + if (shdr == NULL) + /* Something went terribly wrong. */ + return 1; + + offset = shdr->sh_offset; + size = shdr->sh_size; + type = shdr->sh_type; + align = shdr->sh_addralign; + } + + /* If the section has no data (for whatever reason), leave the `d_buf' + pointer NULL. */ + if (size != 0 && type != SHT_NOBITS) + { + /* First a test whether the section is valid at all. */ + size_t entsize; + + if (type == SHT_HASH) + { + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem); + entsize = SH_ENTSIZE_HASH (ehdr); + } + else + { + Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)]; + if (t == ELF_T_VDEF || t == ELF_T_NHDR + || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64)) + entsize = 1; + else + entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t]; + } + + /* We assume it is an array of bytes if it is none of the structured + sections we know of. */ + if (entsize == 0) + entsize = 1; + + if (unlikely (size % entsize != 0)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return 1; + } + + /* We can use the mapped or loaded data if available. */ + if (elf->map_address != NULL) + { + /* First see whether the information in the section header is + valid and it does not ask for too much. */ + if (unlikely (offset + size > elf->maximum_size)) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + return 1; + } + + scn->rawdata_base = scn->rawdata.d.d_buf + = (char *) elf->map_address + elf->start_offset + offset; + } + else if (likely (elf->fildes != -1)) + { + /* We have to read the data from the file. Allocate the needed + memory. */ + scn->rawdata_base = scn->rawdata.d.d_buf + = (char *) malloc (size); + if (scn->rawdata.d.d_buf == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return 1; + } + + ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size, + elf->start_offset + offset); + if (unlikely ((size_t) n != size)) + { + /* Cannot read the data. */ + free (scn->rawdata.d.d_buf); + scn->rawdata_base = scn->rawdata.d.d_buf = NULL; + __libelf_seterrno (ELF_E_READ_ERROR); + return 1; + } + } + else + { + /* The file descriptor is already closed, we cannot get the data + anymore. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + return 1; + } + } + + scn->rawdata.d.d_size = size; + /* Some broken ELF ABI for 64-bit machines use the wrong hash table + entry size. See elf-knowledge.h for more information. */ + if (type == SHT_HASH && elf->class == ELFCLASS64) + { + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem); + scn->rawdata.d.d_type + = (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD); + } + else + scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)]; + scn->rawdata.d.d_off = 0; + scn->rawdata.d.d_align = align; + if (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr))) + scn->rawdata.d.d_version = + elf->state.elf32.ehdr->e_ident[EI_VERSION]; + else + scn->rawdata.d.d_version = + elf->state.elf64.ehdr->e_ident[EI_VERSION]; + + scn->rawdata.s = scn; + + scn->data_read = 1; + + /* We actually read data from the file. At least we tried. */ + scn->flags |= ELF_F_FILEDATA; + + return 0; +} + +int +internal_function +__libelf_set_rawdata (Elf_Scn *scn) +{ + int result; + + if (scn == NULL) + return 1; + + rwlock_wrlock (scn->elf->lock); + result = __libelf_set_rawdata_wrlock (scn); + rwlock_unlock (scn->elf->lock); + + return result; +} + +Elf_Data * +internal_function +__elf_getdata_rdlock (scn, data) + Elf_Scn *scn; + Elf_Data *data; +{ + Elf_Data *result = NULL; + Elf *elf; + int locked = 0; + + if (scn == NULL) + return NULL; + + if (unlikely (scn->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* We will need this multiple times later on. */ + elf = scn->elf; + + /* If `data' is not NULL this means we are not addressing the initial + data in the file. But this also means this data is already read + (since otherwise it is not possible to have a valid `data' pointer) + and all the data structures are initialized as well. In this case + we can simply walk the list of data records. */ + if (data != NULL) + { + Elf_Data_List *runp; + + /* It is not possible that if DATA is not NULL the first entry is + returned. But this also means that there must be a first data + entry. */ + if (scn->data_list_rear == NULL + /* The section the reference data is for must match the section + parameter. */ + || unlikely (((Elf_Data_Scn *) data)->s != scn)) + { + __libelf_seterrno (ELF_E_DATA_MISMATCH); + goto out; + } + + /* We start searching with the first entry. */ + runp = &scn->data_list; + + while (1) + { + /* If `data' does not match any known record punt. */ + if (runp == NULL) + { + __libelf_seterrno (ELF_E_DATA_MISMATCH); + goto out; + } + + if (&runp->data.d == data) + /* Found the entry. */ + break; + + runp = runp->next; + } + + /* Return the data for the next data record. */ + result = runp->next ? &runp->next->data.d : NULL; + goto out; + } + + /* If the data for this section was not yet initialized do it now. */ + if (scn->data_read == 0) + { + /* We cannot acquire a write lock while we are holding a read + lock. Therefore give up the read lock and then get the write + lock. But this means that the data could meanwhile be + modified, therefore start the tests again. */ + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + locked = 1; + + /* Read the data from the file. There is always a file (or + memory region) associated with this descriptor since + otherwise the `data_read' flag would be set. */ + if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0) + /* Something went wrong. The error value is already set. */ + goto out; + } + + /* At this point we know the raw data is available. But it might be + empty in case the section has size zero (for whatever reason). + Now create the converted data in case this is necessary. */ + if (scn->data_list_rear == NULL) + { + if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0) + { + if (!locked) + { + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + if (scn->data_list_rear != NULL) + goto pass; + } + + /* Convert according to the version and the type. */ + convert_data (scn, __libelf_version, elf->class, + (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)) + ? elf->state.elf32.ehdr->e_ident[EI_DATA] + : elf->state.elf64.ehdr->e_ident[EI_DATA]), + scn->rawdata.d.d_size, scn->rawdata.d.d_type); + } + else + { + /* This is an empty or NOBITS section. There is no buffer but + the size information etc is important. */ + scn->data_list.data.d = scn->rawdata.d; + scn->data_list.data.s = scn; + } + + scn->data_list_rear = &scn->data_list; + } + + /* If no data is present we cannot return any. */ + if (scn->data_list_rear != NULL) + pass: + /* Return the first data element in the list. */ + result = &scn->data_list.data.d; + + out: + return result; +} + +Elf_Data * +elf_getdata (scn, data) + Elf_Scn *scn; + Elf_Data *data; +{ + Elf_Data *result; + + if (scn == NULL) + return NULL; + + rwlock_rdlock (scn->elf->lock); + result = __elf_getdata_rdlock (scn, data); + rwlock_unlock (scn->elf->lock); + + return result; +} +INTDEF(elf_getdata) diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c new file mode 100644 index 0000000..3ec2100 --- /dev/null +++ b/libelf/elf_getdata_rawchunk.c @@ -0,0 +1,197 @@ +/* Return converted data from raw chunk of ELF file. + Copyright (C) 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <system.h> +#include "libelfP.h" +#include "common.h" + +Elf_Data * +elf_getdata_rawchunk (elf, offset, size, type) + Elf *elf; + off64_t offset; + size_t size; + Elf_Type type; +{ + if (unlikely (elf == NULL)) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + /* No valid descriptor. */ + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + if (unlikely (offset < 0 || offset + (off64_t) size < offset + || offset + size > elf->maximum_size)) + { + /* Invalid request. */ + __libelf_seterrno (ELF_E_INVALID_OP); + return NULL; + } + + if (type >= ELF_T_NUM) + { + __libelf_seterrno (ELF_E_UNKNOWN_TYPE); + return NULL; + } + + /* Get the raw bytes from the file. */ + void *rawchunk; + int flags = 0; + Elf_Data *result = NULL; + + rwlock_rdlock (elf->lock); + + /* If the file is mmap'ed we can use it directly. */ + if (elf->map_address != NULL) + rawchunk = elf->map_address + elf->start_offset + offset; + else + { + /* We allocate the memory and read the data from the file. */ + rawchunk = malloc (size); + if (rawchunk == NULL) + { + nomem: + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + + /* Read the file content. */ + if (unlikely ((size_t) pread_retry (elf->fildes, rawchunk, size, + elf->start_offset + offset) + != size)) + { + /* Something went wrong. */ + free (rawchunk); + __libelf_seterrno (ELF_E_READ_ERROR); + goto out; + } + + flags = ELF_F_MALLOCED; + } + + /* Copy and/or convert the data as needed for aligned native-order access. */ + size_t align = __libelf_type_align (elf->class, type); + void *buffer; + if (elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA) + { + if (((uintptr_t) rawchunk & (align - 1)) == 0) + /* No need to copy, we can use the raw data. */ + buffer = rawchunk; + else + { + /* A malloc'd block is always sufficiently aligned. */ + assert (flags == 0); + + buffer = malloc (size); + if (unlikely (buffer == NULL)) + goto nomem; + flags = ELF_F_MALLOCED; + + /* The copy will be appropriately aligned for direct access. */ + memcpy (buffer, rawchunk, size); + } + } + else + { + if (flags) + buffer = rawchunk; + else + { + buffer = malloc (size); + if (unlikely (buffer == NULL)) + goto nomem; + flags = ELF_F_MALLOCED; + } + + /* Call the conversion function. */ + (*__elf_xfctstom[LIBELF_EV_IDX][LIBELF_EV_IDX][elf->class - 1][type]) + (buffer, rawchunk, size, 0); + } + + /* Allocate the dummy container to point at this buffer. */ + Elf_Data_Chunk *chunk = calloc (1, sizeof *chunk); + if (chunk == NULL) + { + if (flags) + free (buffer); + goto nomem; + } + + chunk->dummy_scn.elf = elf; + chunk->dummy_scn.flags = flags; + chunk->data.s = &chunk->dummy_scn; + chunk->data.d.d_buf = buffer; + chunk->data.d.d_size = size; + chunk->data.d.d_type = type; + chunk->data.d.d_align = align; + chunk->data.d.d_version = __libelf_version; + + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + + chunk->next = elf->state.elf.rawchunks; + elf->state.elf.rawchunks = chunk; + result = &chunk->data.d; + + out: + rwlock_unlock (elf->lock); + return result; +} diff --git a/libelf/elf_getident.c b/libelf/elf_getident.c new file mode 100644 index 0000000..f9bac10 --- /dev/null +++ b/libelf/elf_getident.c @@ -0,0 +1,84 @@ +/* Retrieve file identification data. + Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "libelfP.h" + + +char * +elf_getident (elf, ptr) + Elf *elf; + size_t *ptr; +{ + /* In case this is no ELF file, the handle is invalid and we return + NULL. */ + if (elf == NULL || elf->kind != ELF_K_ELF) + { + if (ptr != NULL) + *ptr = 0; + return NULL; + } + + /* We already read the ELF header. Return a pointer to it and store + the length in *PTR. */ + if (ptr != NULL) + *ptr = EI_NIDENT; + + return (char *) (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)) + ? elf->state.elf32.ehdr->e_ident + : elf->state.elf64.ehdr->e_ident); +} diff --git a/libelf/elf_getphdrnum.c b/libelf/elf_getphdrnum.c new file mode 100644 index 0000000..edf073e --- /dev/null +++ b/libelf/elf_getphdrnum.c @@ -0,0 +1,116 @@ +/* Return number of program headers in the ELF file. + Copyright (C) 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +int +__elf_getphdrnum_rdlock (elf, dst) + Elf *elf; + size_t *dst; +{ + if (unlikely (elf->state.elf64.ehdr == NULL)) + { + /* Maybe no ELF header was created yet. */ + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + return -1; + } + + *dst = (elf->class == ELFCLASS32 + ? elf->state.elf32.ehdr->e_phnum + : elf->state.elf64.ehdr->e_phnum); + + if (*dst == PN_XNUM) + { + const Elf_ScnList *const scns = (elf->class == ELFCLASS32 + ? &elf->state.elf32.scns + : &elf->state.elf64.scns); + + /* If there are no section headers, perhaps this is really just 65536 + written without PN_XNUM support. Either that or it's bad data. */ + + if (likely (scns->cnt > 0)) + *dst = (elf->class == ELFCLASS32 + ? scns->data[0].shdr.e32->sh_info + : scns->data[0].shdr.e64->sh_info); + } + + return 0; +} + +int +elf_getphdrnum (elf, dst) + Elf *elf; + size_t *dst; +{ + int result; + + if (elf == NULL) + return -1; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_rdlock (elf->lock); + result = __elf_getphdrnum_rdlock (elf, dst); + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_getscn.c b/libelf/elf_getscn.c new file mode 100644 index 0000000..5c14a58 --- /dev/null +++ b/libelf/elf_getscn.c @@ -0,0 +1,110 @@ +/* Get section at specific index. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <stddef.h> +#include <stdlib.h> + +#include "libelfP.h" + + +Elf_Scn * +elf_getscn (elf, idx) + Elf *elf; + size_t idx; +{ + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (elf->lock); + + Elf_Scn *result = NULL; + + /* Find the section in the list. */ + Elf_ScnList *runp = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns); + while (1) + { + if (idx < runp->max) + { + if (idx < runp->cnt) + result = &runp->data[idx]; + else + __libelf_seterrno (ELF_E_INVALID_INDEX); + break; + } + + idx -= runp->max; + + runp = runp->next; + if (runp == NULL) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + break; + } + } + + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_getscn) diff --git a/libelf/elf_getshdrnum.c b/libelf/elf_getshdrnum.c new file mode 100644 index 0000000..ed1149b --- /dev/null +++ b/libelf/elf_getshdrnum.c @@ -0,0 +1,111 @@ +/* Return number of sections in the ELF file. + Copyright (C) 2002, 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +int +__elf_getshdrnum_rdlock (elf, dst) + Elf *elf; + size_t *dst; +{ + int result = 0; + int idx; + + if (elf == NULL) + return -1; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + idx = elf->state.elf.scns_last->cnt; + if (idx != 0 + || (elf->state.elf.scns_last + != (elf->class == ELFCLASS32 + || (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns))) + /* There is at least one section. */ + *dst = 1 + elf->state.elf.scns_last->data[idx - 1].index; + else + *dst = 0; + + return result; +} + +int +elf_getshdrnum (elf, dst) + Elf *elf; + size_t *dst; +{ + int result; + + if (elf == NULL) + return -1; + + rwlock_rdlock (elf->lock); + result = __elf_getshdrnum_rdlock (elf, dst); + rwlock_unlock (elf->lock); + + return result; +} +/* Alias for the deprecated name. */ +strong_alias (elf_getshdrnum, elf_getshnum) diff --git a/libelf/elf_getshdrstrndx.c b/libelf/elf_getshdrstrndx.c new file mode 100644 index 0000000..5e89b34 --- /dev/null +++ b/libelf/elf_getshdrstrndx.c @@ -0,0 +1,205 @@ +/* Return section index of section header string table. + Copyright (C) 2002, 2005, 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <errno.h> +#include <gelf.h> +#include <stddef.h> +#include <unistd.h> + +#include <system.h> +#include "libelfP.h" +#include "common.h" + + +int +elf_getshdrstrndx (elf, dst) + Elf *elf; + size_t *dst; +{ + int result = 0; + + if (elf == NULL) + return -1; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_rdlock (elf->lock); + + /* We rely here on the fact that the `elf' element is a common prefix + of `elf32' and `elf64'. */ + assert (offsetof (struct Elf, state.elf.ehdr) + == offsetof (struct Elf, state.elf32.ehdr)); + assert (sizeof (elf->state.elf.ehdr) + == sizeof (elf->state.elf32.ehdr)); + assert (offsetof (struct Elf, state.elf.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)); + assert (sizeof (elf->state.elf.ehdr) + == sizeof (elf->state.elf64.ehdr)); + + if (unlikely (elf->state.elf.ehdr == NULL)) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + result = -1; + } + else + { + Elf32_Word num; + + num = (elf->class == ELFCLASS32 + ? elf->state.elf32.ehdr->e_shstrndx + : elf->state.elf64.ehdr->e_shstrndx); + + /* Determine whether the index is too big to fit in the ELF + header. */ + if (unlikely (num == SHN_XINDEX)) + { + /* Yes. Search the zeroth section header. */ + if (elf->class == ELFCLASS32) + { + size_t offset; + + if (elf->state.elf32.scns.data[0].shdr.e32 != NULL) + { + num = elf->state.elf32.scns.data[0].shdr.e32->sh_link; + goto success; + } + + offset = elf->state.elf32.ehdr->e_shoff; + + if (elf->map_address != NULL + && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) elf->map_address + offset)) + & (__alignof__ (Elf32_Shdr) - 1)) == 0)) + /* We can directly access the memory. */ + num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link; + else + { + /* We avoid reading in all the section headers. Just read + the first one. */ + Elf32_Shdr shdr_mem; + + if (unlikely (pread_retry (elf->fildes, &shdr_mem, + sizeof (Elf32_Shdr), offset) + != sizeof (Elf32_Shdr))) + { + /* We must be able to read this ELF section header. */ + __libelf_seterrno (ELF_E_INVALID_FILE); + result = -1; + goto out; + } + + if (elf->state.elf32.ehdr->e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (shdr_mem.sh_link); + num = shdr_mem.sh_link; + } + } + else + { + if (elf->state.elf64.scns.data[0].shdr.e64 != NULL) + { + num = elf->state.elf64.scns.data[0].shdr.e64->sh_link; + goto success; + } + + size_t offset = elf->state.elf64.ehdr->e_shoff; + + if (elf->map_address != NULL + && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) elf->map_address + offset)) + & (__alignof__ (Elf64_Shdr) - 1)) == 0)) + /* We can directly access the memory. */ + num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link; + else + { + /* We avoid reading in all the section headers. Just read + the first one. */ + Elf64_Shdr shdr_mem; + + if (unlikely (pread_retry (elf->fildes, &shdr_mem, + sizeof (Elf64_Shdr), offset) + != sizeof (Elf64_Shdr))) + { + /* We must be able to read this ELF section header. */ + __libelf_seterrno (ELF_E_INVALID_FILE); + result = -1; + goto out; + } + + if (elf->state.elf64.ehdr->e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (shdr_mem.sh_link); + num = shdr_mem.sh_link; + } + } + } + + /* Store the result. */ + success: + *dst = num; + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_getshdrstrndx) +/* Alias for the deprecated name. */ +strong_alias (elf_getshdrstrndx, elf_getshstrndx) diff --git a/libelf/elf_gnu_hash.c b/libelf/elf_gnu_hash.c new file mode 100644 index 0000000..efaee43 --- /dev/null +++ b/libelf/elf_gnu_hash.c @@ -0,0 +1,68 @@ +/* GNU-style Hash function used in ELF implementations. + Copyright (C) 2006 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2006. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelfP.h> + +/* Get the implementation. */ +#include <dl-hash.h> + +unsigned long int +elf_gnu_hash (string) + const char *string; +{ + uint_fast32_t h = 5381; + for (unsigned char c = *string; c != '\0'; c = *++string) + h = h * 33 + c; + return h & 0xffffffff; +} diff --git a/libelf/elf_hash.c b/libelf/elf_hash.c new file mode 100644 index 0000000..94c0a85 --- /dev/null +++ b/libelf/elf_hash.c @@ -0,0 +1,66 @@ +/* Hash function used in ELF implementations. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelfP.h> + +/* Get the implementation. */ +#include <dl-hash.h> + +unsigned long int +elf_hash (string) + const char *string; +{ + return _dl_elf_hash (string); +} +INTDEF(elf_hash) diff --git a/libelf/elf_kind.c b/libelf/elf_kind.c new file mode 100644 index 0000000..06aeaa9 --- /dev/null +++ b/libelf/elf_kind.c @@ -0,0 +1,66 @@ +/* Return the kind of file associated with the descriptor. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +Elf_Kind +elf_kind (elf) + Elf *elf; +{ + return elf == NULL ? ELF_K_NONE : elf->kind; +} diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c new file mode 100644 index 0000000..f6468c8 --- /dev/null +++ b/libelf/elf_memory.c @@ -0,0 +1,73 @@ +/* Create descriptor for memory region. + Copyright (C) 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +Elf * +elf_memory (image, size) + char *image; + size_t size; +{ + if (image == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ, NULL); +} diff --git a/libelf/elf_ndxscn.c b/libelf/elf_ndxscn.c new file mode 100644 index 0000000..53082ae --- /dev/null +++ b/libelf/elf_ndxscn.c @@ -0,0 +1,69 @@ +/* Get index of section. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +size_t +elf_ndxscn (scn) + Elf_Scn *scn; +{ + if (scn == NULL) + return SHN_UNDEF; + + return scn->index; +} diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c new file mode 100644 index 0000000..db17ea5 --- /dev/null +++ b/libelf/elf_newdata.c @@ -0,0 +1,130 @@ +/* Create new, empty section data. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> +#include <stdlib.h> + +#include "libelfP.h" + + +Elf_Data * +elf_newdata (Elf_Scn *scn) +{ + Elf_Data_List *result = NULL; + + if (scn == NULL) + return NULL; + + if (unlikely (scn->index == 0)) + { + /* It is not allowed to add something to the 0th section. */ + __libelf_seterrno (ELF_E_NOT_NUL_SECTION); + return NULL; + } + + if (scn->elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)) + ? scn->elf->state.elf32.ehdr == NULL + : scn->elf->state.elf64.ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + return NULL; + } + + rwlock_wrlock (scn->elf->lock); + + if (scn->data_read && scn->data_list_rear == NULL) + { + /* This means the section was created by the user and this is the + first data. */ + result = &scn->data_list; + result->flags = ELF_F_DIRTY; + } + else + { + /* Create a new, empty data descriptor. */ + result = (Elf_Data_List *) calloc (1, sizeof (Elf_Data_List)); + if (result == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + + result->flags = ELF_F_DIRTY | ELF_F_MALLOCED; + + if (scn->data_list_rear == NULL) + /* We create new data without reading/converting the data from the + file. That is fine but we have to remember this. */ + scn->data_list_rear = &scn->data_list; + } + + /* Set the predefined values. */ + result->data.d.d_version = __libelf_version; + + result->data.s = scn; + + /* Add to the end of the list. */ + if (scn->data_list_rear != NULL) + scn->data_list_rear->next = result; + + scn->data_list_rear = result; + + out: + rwlock_unlock (scn->elf->lock); + + /* Please note that the following is thread safe and is also defined + for RESULT == NULL since it still return NULL. */ + return &result->data.d; +} diff --git a/libelf/elf_newscn.c b/libelf/elf_newscn.c new file mode 100644 index 0000000..aefab33 --- /dev/null +++ b/libelf/elf_newscn.c @@ -0,0 +1,176 @@ +/* Append new section. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + + +Elf_Scn * +elf_newscn (elf) + Elf *elf; +{ + Elf_Scn *result = NULL; + bool first = false; + + if (elf == NULL) + return NULL; + + /* We rely on the prefix of the `elf', `elf32', and `elf64' element + being the same. */ + assert (offsetof (Elf, state.elf.scns_last) + == offsetof (Elf, state.elf32.scns_last)); + assert (offsetof (Elf, state.elf.scns_last) + == offsetof (Elf, state.elf64.scns_last)); + assert (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns)); + + rwlock_wrlock (elf->lock); + + again: + if (elf->state.elf.scns_last->cnt < elf->state.elf.scns_last->max) + { + result = &elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt]; + + if (++elf->state.elf.scns_last->cnt == 1 + && (elf->state.elf.scns_last + == (elf->class == ELFCLASS32 + || (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns))) + /* This is zeroth section. */ + first = true; + else + { + assert (elf->state.elf.scns_last->cnt > 1); + result->index = result[-1].index + 1; + } + } + else + { + /* We must allocate a new element. */ + Elf_ScnList *newp; + + assert (elf->state.elf.scnincr > 0); + + newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList) + + ((elf->state.elf.scnincr *= 2) + * sizeof (Elf_Scn)), 1); + if (newp == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + + result = &newp->data[0]; + + /* One section used. */ + ++newp->cnt; + + /* This is the number of sections we allocated. */ + newp->max = elf->state.elf.scnincr; + + /* Remember the index for the first section in this block. */ + newp->data[0].index + = 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->max - 1].index; + + /* Enqueue the new list element. */ + elf->state.elf.scns_last = elf->state.elf.scns_last->next = newp; + } + + /* Create a section header for this section. */ + if (elf->class == ELFCLASS32) + { + result->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr)); + if (result->shdr.e32 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + else + { + result->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr)); + if (result->shdr.e64 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + + result->elf = elf; + result->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED; + result->list = elf->state.elf.scns_last; + + /* Initialize the data part. */ + result->data_read = 1; + if (unlikely (first)) + { + /* For the first section we mark the data as already available. */ + //result->data_list_rear = &result->data_list; + first = false; + goto again; + } + + result->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_next.c b/libelf/elf_next.c new file mode 100644 index 0000000..196c65a --- /dev/null +++ b/libelf/elf_next.c @@ -0,0 +1,94 @@ +/* Advance in archive to next element. + Copyright (C) 1998-2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +Elf_Cmd +elf_next (elf) + Elf *elf; +{ + Elf *parent; + Elf_Cmd ret; + + /* Be gratious, the specs demand it. */ + if (elf == NULL || elf->parent == NULL) + return ELF_C_NULL; + + /* We can be sure the parent is an archive. */ + parent = elf->parent; + assert (parent->kind == ELF_K_AR); + + rwlock_wrlock (parent->lock); + + /* Now advance the offset. */ + parent->state.ar.offset += (sizeof (struct ar_hdr) + + ((parent->state.ar.elf_ar_hdr.ar_size + 1) + & ~1l)); + + /* Get the next archive header. */ + ret = __libelf_next_arhdr_wrlock (parent) != 0 ? ELF_C_NULL : elf->cmd; + + /* If necessary, mark the archive header as unusable. */ + if (ret == ELF_C_NULL) + parent->state.ar.elf_ar_hdr.ar_name = NULL; + + rwlock_unlock (parent->lock); + + return ret; +} diff --git a/libelf/elf_nextscn.c b/libelf/elf_nextscn.c new file mode 100644 index 0000000..a1842bb --- /dev/null +++ b/libelf/elf_nextscn.c @@ -0,0 +1,110 @@ +/* Get next section. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +Elf_Scn * +elf_nextscn (elf, scn) + Elf *elf; + Elf_Scn *scn; +{ + Elf_Scn *result = NULL; + + if (elf == NULL) + return NULL; + + rwlock_rdlock (elf->lock); + + if (scn == NULL) + { + /* If no section handle is given return the first (not 0th) section. */ + if (elf->class == ELFCLASS32 + || (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns))) + { + if (elf->state.elf32.scns.cnt > 1) + result = &elf->state.elf32.scns.data[1]; + } + else + { + if (elf->state.elf64.scns.cnt > 1) + result = &elf->state.elf64.scns.data[1]; + } + } + else + { + Elf_ScnList *list = scn->list; + + if (scn + 1 < &list->data[list->cnt]) + result = scn + 1; + else if (scn + 1 == &list->data[list->max] + && (list = list->next) != NULL) + { + /* If there is another element in the section list it must + have at least one entry. */ + assert (list->cnt > 0); + result = &list->data[0]; + } + } + + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_nextscn) diff --git a/libelf/elf_rand.c b/libelf/elf_rand.c new file mode 100644 index 0000000..a766d38 --- /dev/null +++ b/libelf/elf_rand.c @@ -0,0 +1,86 @@ +/* Select specific element in archive. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +size_t +elf_rand (elf, offset) + Elf *elf; + size_t offset; +{ + /* Be gratious, the specs demand it. */ + if (elf == NULL || elf->kind != ELF_K_AR) + return 0; + + rwlock_wrlock (elf->lock); + + /* Save the old offset and set the offset. */ + elf->state.ar.offset = elf->start_offset + offset; + + /* Get the next archive header. */ + if (__libelf_next_arhdr_wrlock (elf) != 0) + { + /* Mark the archive header as unusable. */ + elf->state.ar.elf_ar_hdr.ar_name = NULL; + return 0; + } + + rwlock_unlock (elf->lock); + + return offset; +} diff --git a/libelf/elf_rawdata.c b/libelf/elf_rawdata.c new file mode 100644 index 0000000..b8bb0f4 --- /dev/null +++ b/libelf/elf_rawdata.c @@ -0,0 +1,99 @@ +/* Return raw section content. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> + +#include "libelfP.h" + + +Elf_Data * +elf_rawdata (scn, data) + Elf_Scn *scn; + Elf_Data *data; +{ + if (scn == NULL || scn->elf->kind != ELF_K_ELF) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* If `data' is not NULL this means we are not addressing the initial + data in the file. But this also means this data is already read + (since otherwise it is not possible to have a valid `data' pointer) + and all the data structures are initialized as well. In this case + we can simply walk the list of data records. */ + if (data != NULL + || (scn->data_read != 0 && (scn->flags & ELF_F_FILEDATA) == 0)) + { + /* We don't allow accessing any but the data read from the file + as raw. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return NULL; + } + + /* If the data for this section was not yet initialized do it now. */ + if (scn->data_read == 0) + { + /* First thing we do is to read the data from the file. There is + always a file (or memory region) associated with this descriptor + since otherwise the `data_read' flag would be set. */ + if (__libelf_set_rawdata (scn) != 0) + /* Something went wrong. The error value is already set. */ + return NULL; + } + + /* Return the first data element in the list. */ + return &scn->rawdata.d; +} +INTDEF(elf_rawdata) diff --git a/libelf/elf_rawfile.c b/libelf/elf_rawfile.c new file mode 100644 index 0000000..a62a354 --- /dev/null +++ b/libelf/elf_rawfile.c @@ -0,0 +1,90 @@ +/* Retrieve uninterpreted file contents. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +char * +elf_rawfile (elf, ptr) + Elf *elf; + size_t *ptr; +{ + char *result; + + if (elf == NULL) + { + /* No valid descriptor. */ + __libelf_seterrno (ELF_E_INVALID_HANDLE); + error_out: + if (ptr != NULL) + *ptr = 0; + return NULL; + } + + /* If the file is not mmap'ed and not previously loaded, do it now. */ + if (elf->map_address == NULL && __libelf_readall (elf) == NULL) + goto error_out; + + rwlock_rdlock (elf->lock); + if (ptr != NULL) + *ptr = elf->maximum_size; + + result = (char *) elf->map_address + elf->start_offset; + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c new file mode 100644 index 0000000..1f59932 --- /dev/null +++ b/libelf/elf_readall.c @@ -0,0 +1,173 @@ +/* Read all of the file associated with the descriptor. + Copyright (C) 1998-2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> +#include <sys/stat.h> + +#include <system.h> +#include "libelfP.h" +#include "common.h" + + +static void +set_address (Elf *elf, size_t offset) +{ + if (elf->kind == ELF_K_AR) + { + Elf *child = elf->state.ar.children; + + while (child != NULL) + { + if (child->map_address == NULL) + { + child->map_address = elf->map_address; + child->start_offset -= offset; + if (child->kind == ELF_K_AR) + child->state.ar.offset -= offset; + + set_address (child, offset); + } + + child = child->next; + } + } +} + + +char * +__libelf_readall (elf) + Elf *elf; +{ + /* Get the file. */ + rwlock_wrlock (elf->lock); + + if (elf->map_address == NULL && unlikely (elf->fildes == -1)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + rwlock_unlock (elf->lock); + return NULL; + } + + /* If the file is not mmap'ed and not previously loaded, do it now. */ + if (elf->map_address == NULL) + { + char *mem = NULL; + + /* If this is an archive and we have derived descriptors get the + locks for all of them. */ + libelf_acquire_all (elf); + + if (elf->maximum_size == ~((size_t) 0)) + { + /* We don't yet know how large the file is. Determine that now. */ + struct stat st; + + if (fstat (elf->fildes, &st) < 0) + goto read_error; + + if (sizeof (size_t) >= sizeof (st.st_size) + || st.st_size <= ~((size_t) 0)) + elf->maximum_size = (size_t) st.st_size; + else + { + errno = EOVERFLOW; + goto read_error; + } + } + + /* Allocate all the memory we need. */ + mem = (char *) malloc (elf->maximum_size); + if (mem != NULL) + { + /* Read the file content. */ + if (unlikely ((size_t) pread_retry (elf->fildes, mem, + elf->maximum_size, + elf->start_offset) + != elf->maximum_size)) + { + /* Something went wrong. */ + read_error: + __libelf_seterrno (ELF_E_READ_ERROR); + free (mem); + } + else + { + /* Remember the address. */ + elf->map_address = mem; + + /* Also remember that we allocated the memory. */ + elf->flags |= ELF_F_MALLOCED; + + /* Propagate the information down to all children and + their children. */ + set_address (elf, elf->start_offset); + + /* Correct the own offsets. */ + if (elf->kind == ELF_K_AR) + elf->state.ar.offset -= elf->start_offset; + elf->start_offset = 0; + } + } + else + __libelf_seterrno (ELF_E_NOMEM); + + /* Free the locks on the children. */ + libelf_release_all (elf); + } + + rwlock_unlock (elf->lock); + + return (char *) elf->map_address; +} diff --git a/libelf/elf_scnshndx.c b/libelf/elf_scnshndx.c new file mode 100644 index 0000000..987d23e --- /dev/null +++ b/libelf/elf_scnshndx.c @@ -0,0 +1,71 @@ +/* Get the section index of the extended section index table. + Copyright (C) 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2007. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "libelfP.h" + + +int +elf_scnshndx (Elf_Scn *scn) +{ + if (unlikely (scn->shndx_index == 0)) + { + /* We do not have the value yet. We get it as a side effect of + getting a section header. */ + GElf_Shdr shdr_mem; + (void) INTUSE(gelf_getshdr) (scn, &shdr_mem); + } + + return scn->shndx_index; +} +INTDEF(elf_scnshndx) diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c new file mode 100644 index 0000000..7b837b0 --- /dev/null +++ b/libelf/elf_strptr.c @@ -0,0 +1,182 @@ +/* Return string pointer from string section. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008, 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +char * +elf_strptr (elf, idx, offset) + Elf *elf; + size_t idx; + size_t offset; +{ + if (elf == NULL) + return NULL; + + if (elf->kind != ELF_K_ELF) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (elf->lock); + + char *result = NULL; + Elf_Scn *strscn; + + /* Find the section in the list. */ + Elf_ScnList *runp = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns); + while (1) + { + if (idx < runp->max) + { + if (idx < runp->cnt) + strscn = &runp->data[idx]; + else + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + break; + } + + idx -= runp->max; + + runp = runp->next; + if (runp == NULL) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + } + + if (elf->class == ELFCLASS32) + { + if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB)) + { + /* This is no string section. */ + __libelf_seterrno (ELF_E_INVALID_SECTION); + goto out; + } + + if (unlikely (offset >= strscn->shdr.e32->sh_size)) + { + /* The given offset is too big, it is beyond this section. */ + __libelf_seterrno (ELF_E_OFFSET_RANGE); + goto out; + } + } + else + { + if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB)) + { + /* This is no string section. */ + __libelf_seterrno (ELF_E_INVALID_SECTION); + goto out; + } + + if (unlikely (offset >= strscn->shdr.e64->sh_size)) + { + /* The given offset is too big, it is beyond this section. */ + __libelf_seterrno (ELF_E_OFFSET_RANGE); + goto out; + } + } + + if (strscn->rawdata_base == NULL && ! strscn->data_read) + { + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + if (strscn->rawdata_base == NULL && ! strscn->data_read + /* Read the section data. */ + && __libelf_set_rawdata_wrlock (strscn) != 0) + goto out; + } + + if (likely (strscn->rawdata_base != NULL)) + // XXX Is this correct if a file is read and then new data is added + // XXX to the string section? Likely needs to check offset against + // XXX size of rawdata_base buffer and then iterate over rest of the + // XXX list. + result = &strscn->rawdata_base[offset]; + else + { + /* This is a file which is currently created. Use the list of + data blocks. */ + struct Elf_Data_List *dl = &strscn->data_list; + while (dl != NULL) + { + if (offset >= (size_t) dl->data.d.d_off + && offset < dl->data.d.d_off + dl->data.d.d_size) + { + result = (char *) dl->data.d.d_buf + (offset - dl->data.d.d_off); + break; + } + + dl = dl->next; + } + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_strptr) diff --git a/libelf/elf_update.c b/libelf/elf_update.c new file mode 100644 index 0000000..5daece4 --- /dev/null +++ b/libelf/elf_update.c @@ -0,0 +1,224 @@ +/* Update data structures for changes and write them out. + Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelf.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> + +#include "libelfP.h" + + +static off_t +write_file (Elf *elf, off_t size, int change_bo, size_t shnum) +{ + int class = elf->class; + + /* Check the mode bits now, before modification might change them. */ + struct stat st; + if (unlikely (fstat (elf->fildes, &st) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } + + /* Adjust the size in any case. We do this even if we use `write'. + We cannot do this if this file is in an archive. We also don't + do it *now* if we are shortening the file since this would + prevent programs to use the data of the file in generating the + new file. We truncate the file later in this case. */ + if (elf->parent == NULL + && (elf->maximum_size == ~((size_t) 0) + || (size_t) size > elf->maximum_size) + && unlikely (ftruncate (elf->fildes, size) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } + + /* Try to map the file if this isn't done yet. */ + if (elf->map_address == NULL && elf->cmd == ELF_C_WRITE_MMAP) + { +#if _MUDFLAP + /* Mudflap doesn't grok that our mmap'd data is ok. */ +#else + elf->map_address = mmap (NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, elf->fildes, 0); + if (unlikely (elf->map_address == MAP_FAILED)) + elf->map_address = NULL; +#endif + } + + if (elf->map_address != NULL) + { + /* The file is mmaped. */ + if ((class == ELFCLASS32 + ? __elf32_updatemmap (elf, change_bo, shnum) + : __elf64_updatemmap (elf, change_bo, shnum)) != 0) + /* Some problem while writing. */ + size = -1; + } + else + { + /* The file is not mmaped. */ + if ((class == ELFCLASS32 + ? __elf32_updatefile (elf, change_bo, shnum) + : __elf64_updatefile (elf, change_bo, shnum)) != 0) + /* Some problem while writing. */ + size = -1; + } + + if (size != -1 + && elf->parent == NULL + && elf->maximum_size != ~((size_t) 0) + && (size_t) size < elf->maximum_size + && unlikely (ftruncate (elf->fildes, size) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + size = -1; + } + + /* POSIX says that ftruncate and write may clear the S_ISUID and S_ISGID + mode bits. So make sure we restore them afterwards if they were set. + This is not atomic if someone else chmod's the file while we operate. */ + if (size != -1 + && unlikely (st.st_mode & (S_ISUID | S_ISGID)) + /* fchmod ignores the bits we cannot change. */ + && unlikely (fchmod (elf->fildes, st.st_mode) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + size = -1; + } + + if (size != -1 && elf->parent == NULL) + elf->maximum_size = size; + + return size; +} + + +off_t +elf_update (elf, cmd) + Elf *elf; + Elf_Cmd cmd; +{ + size_t shnum; + off_t size; + int change_bo = 0; + + if (cmd != ELF_C_NULL + && cmd != ELF_C_WRITE + && unlikely (cmd != ELF_C_WRITE_MMAP)) + { + __libelf_seterrno (ELF_E_INVALID_CMD); + return -1; + } + + if (elf == NULL) + return -1; + + if (elf->kind != ELF_K_ELF) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_wrlock (elf->lock); + + /* Make sure we have an ELF header. */ + if (elf->state.elf.ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + size = -1; + goto out; + } + + /* Determine the number of sections. */ + shnum = (elf->state.elf.scns_last->cnt == 0 + ? 0 + : 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt - 1].index); + + /* Update the ELF descriptor. First, place the program header. It + will come right after the ELF header. The count the size of all + sections and finally place the section table. */ + size = (elf->class == ELFCLASS32 + ? __elf32_updatenull_wrlock (elf, &change_bo, shnum) + : __elf64_updatenull_wrlock (elf, &change_bo, shnum)); + if (likely (size != -1) + /* See whether we actually have to write out the data. */ + && (cmd == ELF_C_WRITE || cmd == ELF_C_WRITE_MMAP)) + { + if (elf->cmd != ELF_C_RDWR + && elf->cmd != ELF_C_RDWR_MMAP + && elf->cmd != ELF_C_WRITE + && unlikely (elf->cmd != ELF_C_WRITE_MMAP)) + { + __libelf_seterrno (ELF_E_UPDATE_RO); + size = -1; + } + else if (unlikely (elf->fildes == -1)) + { + /* We closed the file already. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + size = -1; + } + else + size = write_file (elf, size, change_bo, shnum); + } + + out: + rwlock_unlock (elf->lock); + + return size; +} diff --git a/libelf/elf_version.c b/libelf/elf_version.c new file mode 100644 index 0000000..cbed496 --- /dev/null +++ b/libelf/elf_version.c @@ -0,0 +1,91 @@ +/* Coordinate ELF library and application versions. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libelfP.h> + + +/* Is the version initialized? */ +int __libelf_version_initialized; + +/* Currently selected version. */ +unsigned int __libelf_version = EV_CURRENT; + + +unsigned int +elf_version (version) + unsigned int version; +{ + if (version == EV_NONE) + return __libelf_version; + + if (likely (version < EV_NUM)) + { + /* Phew, we know this version. */ + unsigned int last_version = __libelf_version; + + /* Store the new version. */ + __libelf_version = version; + + /* Signal that the version is now initialized. */ + __libelf_version_initialized = 1; + + /* And return the last version. */ + return last_version; + } + + /* We cannot handle this version. */ + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return EV_NONE; +} +INTDEF(elf_version) diff --git a/libelf/exttypes.h b/libelf/exttypes.h new file mode 100644 index 0000000..2b15667 --- /dev/null +++ b/libelf/exttypes.h @@ -0,0 +1,123 @@ +/* External ELF types. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _EXTTYPES_H +#define _EXTTYPES_H 1 + +/* Integral types. */ +typedef char Elf32_Ext_Addr[ELF32_FSZ_ADDR]; +typedef char Elf32_Ext_Off[ELF32_FSZ_OFF]; +typedef char Elf32_Ext_Half[ELF32_FSZ_HALF]; +typedef char Elf32_Ext_Sword[ELF32_FSZ_SWORD]; +typedef char Elf32_Ext_Word[ELF32_FSZ_WORD]; +typedef char Elf32_Ext_Sxword[ELF32_FSZ_SXWORD]; +typedef char Elf32_Ext_Xword[ELF32_FSZ_XWORD]; + +typedef char Elf64_Ext_Addr[ELF64_FSZ_ADDR]; +typedef char Elf64_Ext_Off[ELF64_FSZ_OFF]; +typedef char Elf64_Ext_Half[ELF64_FSZ_HALF]; +typedef char Elf64_Ext_Sword[ELF64_FSZ_SWORD]; +typedef char Elf64_Ext_Word[ELF64_FSZ_WORD]; +typedef char Elf64_Ext_Sxword[ELF64_FSZ_SXWORD]; +typedef char Elf64_Ext_Xword[ELF64_FSZ_XWORD]; + + +/* Define the composed types. */ +#define START(Bits, Name, EName) typedef struct { +#define END(Bits, Name) } ElfW2(Bits, Name) +#define TYPE_NAME(Type, Name) Type Name; +#define TYPE_EXTRA(Text) Text +#define TYPE_XLATE(Text) + +/* Get the abstract definitions. */ +#include "abstract.h" + +/* And define the types. */ +Ehdr32 (Ext_); +Phdr32 (Ext_); +Shdr32 (Ext_); +Sym32 (Ext_); +Rel32 (Ext_); +Rela32 (Ext_); +Note32 (Ext_); +Dyn32 (Ext_); +Verdef32 (Ext_); +Verdaux32 (Ext_); +Verneed32 (Ext_); +Vernaux32 (Ext_); +Syminfo32 (Ext_); +Move32 (Ext_); +Lib32 (Ext_); +auxv_t32 (Ext_); + +Ehdr64 (Ext_); +Phdr64 (Ext_); +Shdr64 (Ext_); +Sym64 (Ext_); +Rel64 (Ext_); +Rela64 (Ext_); +Note64 (Ext_); +Dyn64 (Ext_); +Verdef64 (Ext_); +Verdaux64 (Ext_); +Verneed64 (Ext_); +Vernaux64 (Ext_); +Syminfo64 (Ext_); +Move64 (Ext_); +Lib64 (Ext_); +auxv_t64 (Ext_); + +#undef START +#undef END +#undef TYPE_NAME +#undef TYPE_EXTRA +#undef TYPE_XLATE + +#endif /* exttypes.h */ diff --git a/libelf/gelf.h b/libelf/gelf.h new file mode 100644 index 0000000..533e15a --- /dev/null +++ b/libelf/gelf.h @@ -0,0 +1,353 @@ +/* This file defines generic ELF types, structures, and macros. + Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _GELF_H +#define _GELF_H 1 + +#include <libelf.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Class independent type definitions. Correctly speaking this is not + true. We assume that 64-bit binaries are the largest class and + therefore all other classes can be represented without loss. */ + +/* Type for a 16-bit quantity. */ +typedef Elf64_Half GElf_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef Elf64_Word GElf_Word; +typedef Elf64_Sword GElf_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef Elf64_Xword GElf_Xword; +typedef Elf64_Sxword GElf_Sxword; + +/* Type of addresses. */ +typedef Elf64_Addr GElf_Addr; + +/* Type of file offsets. */ +typedef Elf64_Off GElf_Off; + + +/* The ELF file header. This appears at the start of every ELF file. */ +typedef Elf64_Ehdr GElf_Ehdr; + +/* Section header. */ +typedef Elf64_Shdr GElf_Shdr; + +/* Section index. */ +/* XXX This should probably be a larger type in preparation of times when + regular section indices can be larger. */ +typedef Elf64_Section GElf_Section; + +/* Symbol table entry. */ +typedef Elf64_Sym GElf_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ +typedef Elf64_Syminfo GElf_Syminfo; + +/* Relocation table entry without addend (in section of type SHT_REL). */ +typedef Elf64_Rel GElf_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ +typedef Elf64_Rela GElf_Rela; + +/* Program segment header. */ +typedef Elf64_Phdr GElf_Phdr; + +/* Dynamic section entry. */ +typedef Elf64_Dyn GElf_Dyn; + + +/* Version definition sections. */ +typedef Elf64_Verdef GElf_Verdef; + +/* Auxialiary version information. */ +typedef Elf64_Verdaux GElf_Verdaux; + +/* Version dependency section. */ +typedef Elf64_Verneed GElf_Verneed; + +/* Auxiliary needed version information. */ +typedef Elf64_Vernaux GElf_Vernaux; + + +/* Type for version symbol information. */ +typedef Elf64_Versym GElf_Versym; + + +/* Auxiliary vector. */ +typedef Elf64_auxv_t GElf_auxv_t; + + +/* Note section contents. */ +typedef Elf64_Nhdr GElf_Nhdr; + + +/* Move structure. */ +typedef Elf64_Move GElf_Move; + + +/* Library list structure. */ +typedef Elf64_Lib GElf_Lib; + + +/* How to extract and insert information held in the st_info field. */ + +#define GELF_ST_BIND(val) ELF64_ST_BIND (val) +#define GELF_ST_TYPE(val) ELF64_ST_TYPE (val) +#define GELF_ST_INFO(bind, type) ELF64_ST_INFO (bind, type) + +/* How to extract information held in the st_other field. */ + +#define GELF_ST_VISIBILITY(val) ELF64_ST_VISIBILITY (val) + + +/* How to extract and insert information held in the r_info field. */ + +#define GELF_R_SYM(info) ELF64_R_SYM (info) +#define GELF_R_TYPE(info) ELF64_R_TYPE (info) +#define GELF_R_INFO(sym, type) ELF64_R_INFO (sym, type) + + +/* How to extract and insert information held in the m_info field. */ +#define GELF_M_SYM(info) ELF64_M_SYM (info) +#define GELF_M_SIZE(info) ELF64_M_SIZE (info) +#define GELF_M_INFO(sym, size) ELF64_M_INFO (sym, size) + + +/* Get class of the file associated with ELF. */ +extern int gelf_getclass (Elf *__elf); + + +/* Return size of array of COUNT elemeents of the type denoted by TYPE + in the external representation. The binary class is taken from ELF. + The result is based on version VERSION of the ELF standard. */ +extern size_t gelf_fsize (Elf *__elf, Elf_Type __type, size_t __count, + unsigned int __version); + +/* Retrieve object file header. */ +extern GElf_Ehdr *gelf_getehdr (Elf *__elf, GElf_Ehdr *__dest); + +/* Update the ELF header. */ +extern int gelf_update_ehdr (Elf *__elf, GElf_Ehdr *__src); + +/* Create new ELF header if none exists. */ +extern unsigned long int gelf_newehdr (Elf *__elf, int __class); + +/* Get section at OFFSET. */ +extern Elf_Scn *gelf_offscn (Elf *__elf, GElf_Off __offset); + +/* Retrieve section header. */ +extern GElf_Shdr *gelf_getshdr (Elf_Scn *__scn, GElf_Shdr *__dst); + +/* Update section header. */ +extern int gelf_update_shdr (Elf_Scn *__scn, GElf_Shdr *__src); + +/* Retrieve program header table entry. */ +extern GElf_Phdr *gelf_getphdr (Elf *__elf, int __ndx, GElf_Phdr *__dst); + +/* Update the program header. */ +extern int gelf_update_phdr (Elf *__elf, int __ndx, GElf_Phdr *__src); + +/* Create new program header with PHNUM entries. */ +extern unsigned long int gelf_newphdr (Elf *__elf, size_t __phnum); + + +/* Convert data structure from the representation in the file represented + by ELF to their memory representation. */ +extern Elf_Data *gelf_xlatetom (Elf *__elf, Elf_Data *__dest, + const Elf_Data *__src, unsigned int __encode); + +/* Convert data structure from to the representation in memory + represented by ELF file representation. */ +extern Elf_Data *gelf_xlatetof (Elf *__elf, Elf_Data *__dest, + const Elf_Data *__src, unsigned int __encode); + + +/* Retrieve REL relocation info at the given index. */ +extern GElf_Rel *gelf_getrel (Elf_Data *__data, int __ndx, GElf_Rel *__dst); + +/* Retrieve RELA relocation info at the given index. */ +extern GElf_Rela *gelf_getrela (Elf_Data *__data, int __ndx, GElf_Rela *__dst); + +/* Update REL relocation information at given index. */ +extern int gelf_update_rel (Elf_Data *__dst, int __ndx, GElf_Rel *__src); + +/* Update RELA relocation information at given index. */ +extern int gelf_update_rela (Elf_Data *__dst, int __ndx, GElf_Rela *__src); + + +/* Retrieve symbol information from the symbol table at the given index. */ +extern GElf_Sym *gelf_getsym (Elf_Data *__data, int __ndx, GElf_Sym *__dst); + +/* Update symbol information in the symbol table at the given index. */ +extern int gelf_update_sym (Elf_Data *__data, int __ndx, GElf_Sym *__src); + + +/* Retrieve symbol information and separate section index from the + symbol table at the given index. */ +extern GElf_Sym *gelf_getsymshndx (Elf_Data *__symdata, Elf_Data *__shndxdata, + int __ndx, GElf_Sym *__sym, + Elf32_Word *__xshndx); + +/* Update symbol information and separate section index in the symbol + table at the given index. */ +extern int gelf_update_symshndx (Elf_Data *__symdata, Elf_Data *__shndxdata, + int __ndx, GElf_Sym *__sym, + Elf32_Word __xshndx); + + +/* Retrieve additional symbol information from the symbol table at the + given index. */ +extern GElf_Syminfo *gelf_getsyminfo (Elf_Data *__data, int __ndx, + GElf_Syminfo *__dst); + +/* Update additional symbol information in the symbol table at the + given index. */ +extern int gelf_update_syminfo (Elf_Data *__data, int __ndx, + GElf_Syminfo *__src); + + +/* Get information from dynamic table at the given index. */ +extern GElf_Dyn *gelf_getdyn (Elf_Data *__data, int __ndx, GElf_Dyn *__dst); + +/* Update information in dynamic table at the given index. */ +extern int gelf_update_dyn (Elf_Data *__dst, int __ndx, GElf_Dyn *__src); + + +/* Get move structure at the given index. */ +extern GElf_Move *gelf_getmove (Elf_Data *__data, int __ndx, GElf_Move *__dst); + +/* Update move structure at the given index. */ +extern int gelf_update_move (Elf_Data *__data, int __ndx, + GElf_Move *__src); + + +/* Get library from table at the given index. */ +extern GElf_Lib *gelf_getlib (Elf_Data *__data, int __ndx, GElf_Lib *__dst); + +/* Update library in table at the given index. */ +extern int gelf_update_lib (Elf_Data *__data, int __ndx, GElf_Lib *__src); + + + +/* Retrieve symbol version information at given index. */ +extern GElf_Versym *gelf_getversym (Elf_Data *__data, int __ndx, + GElf_Versym *__dst); + +/* Update symbol version information. */ +extern int gelf_update_versym (Elf_Data *__data, int __ndx, + GElf_Versym *__src); + + +/* Retrieve required symbol version information at given offset. */ +extern GElf_Verneed *gelf_getverneed (Elf_Data *__data, int __offset, + GElf_Verneed *__dst); + +/* Update required symbol version information. */ +extern int gelf_update_verneed (Elf_Data *__data, int __offset, + GElf_Verneed *__src); + +/* Retrieve additional required symbol version information at given offset. */ +extern GElf_Vernaux *gelf_getvernaux (Elf_Data *__data, int __offset, + GElf_Vernaux *__dst); + +/* Update additional required symbol version information. */ +extern int gelf_update_vernaux (Elf_Data *__data, int __offset, + GElf_Vernaux *__src); + + +/* Retrieve symbol version definition information at given offset. */ +extern GElf_Verdef *gelf_getverdef (Elf_Data *__data, int __offset, + GElf_Verdef *__dst); + +/* Update symbol version definition information. */ +extern int gelf_update_verdef (Elf_Data *__data, int __offset, + GElf_Verdef *__src); + +/* Retrieve additional symbol version definition information at given + offset. */ +extern GElf_Verdaux *gelf_getverdaux (Elf_Data *__data, int __offset, + GElf_Verdaux *__dst); + +/* Update additional symbol version definition information. */ +extern int gelf_update_verdaux (Elf_Data *__data, int __offset, + GElf_Verdaux *__src); + + +/* Get auxv entry at the given index. */ +extern GElf_auxv_t *gelf_getauxv (Elf_Data *__data, int __ndx, + GElf_auxv_t *__dst); + +/* Update auxv entry at the given index. */ +extern int gelf_update_auxv (Elf_Data *__data, int __ndx, GElf_auxv_t *__src); + + +/* Get note header at the given offset into the data, and the offsets of + the note's name and descriptor data. Returns the offset of the next + note header, or 0 for an invalid offset or corrupt note header. */ +extern size_t gelf_getnote (Elf_Data *__data, size_t __offset, + GElf_Nhdr *__result, + size_t *__name_offset, size_t *__desc_offset); + + +/* Compute simple checksum from permanent parts of the ELF file. */ +extern long int gelf_checksum (Elf *__elf); + +#ifdef __cplusplus +} +#endif + +#endif /* gelf.h */ diff --git a/libelf/gelf_checksum.c b/libelf/gelf_checksum.c new file mode 100644 index 0000000..fb0daa5 --- /dev/null +++ b/libelf/gelf_checksum.c @@ -0,0 +1,70 @@ +/* Convert from file to memory representation. Generic ELF version. + Copyright (C) 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +long int +gelf_checksum (elf) + Elf *elf; +{ + if (elf == NULL) + return -1l; + + return (elf->class == ELFCLASS32 + ? INTUSE(elf32_checksum) (elf) : INTUSE(elf64_checksum) (elf)); +} diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c new file mode 100644 index 0000000..7a9a308 --- /dev/null +++ b/libelf/gelf_fsize.c @@ -0,0 +1,132 @@ +/* Return the size of an object file type. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +/* These are the sizes for all the known types. */ +const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] = +{ + /* We have no entry for EV_NONE since we have to set an error. */ + [EV_CURRENT - 1] = { + [ELFCLASS32 - 1] = { +#define TYPE_SIZES(LIBELFBITS) \ + [ELF_T_ADDR] = ELFW2(LIBELFBITS, FSZ_ADDR), \ + [ELF_T_OFF] = ELFW2(LIBELFBITS, FSZ_OFF), \ + [ELF_T_BYTE] = 1, \ + [ELF_T_HALF] = ELFW2(LIBELFBITS, FSZ_HALF), \ + [ELF_T_WORD] = ELFW2(LIBELFBITS, FSZ_WORD), \ + [ELF_T_SWORD] = ELFW2(LIBELFBITS, FSZ_SWORD), \ + [ELF_T_XWORD] = ELFW2(LIBELFBITS, FSZ_XWORD), \ + [ELF_T_SXWORD] = ELFW2(LIBELFBITS, FSZ_SXWORD), \ + [ELF_T_EHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)), \ + [ELF_T_SHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Shdr)), \ + [ELF_T_SYM] = sizeof (ElfW2(LIBELFBITS, Ext_Sym)), \ + [ELF_T_REL] = sizeof (ElfW2(LIBELFBITS, Ext_Rel)), \ + [ELF_T_RELA] = sizeof (ElfW2(LIBELFBITS, Ext_Rela)), \ + [ELF_T_PHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Phdr)), \ + [ELF_T_DYN] = sizeof (ElfW2(LIBELFBITS, Ext_Dyn)), \ + [ELF_T_VDEF] = sizeof (ElfW2(LIBELFBITS, Ext_Verdef)), \ + [ELF_T_VDAUX] = sizeof (ElfW2(LIBELFBITS, Ext_Verdaux)), \ + [ELF_T_VNEED] = sizeof (ElfW2(LIBELFBITS, Ext_Verneed)), \ + [ELF_T_VNAUX] = sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)), \ + [ELF_T_NHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)), \ + [ELF_T_SYMINFO] = sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)), \ + [ELF_T_MOVE] = sizeof (ElfW2(LIBELFBITS, Ext_Move)), \ + [ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \ + [ELF_T_AUXV] = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)), \ + [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD) + TYPE_SIZES (32) + }, + [ELFCLASS64 - 1] = { + TYPE_SIZES (64) + } + } +}; + + +size_t +gelf_fsize (elf, type, count, version) + Elf *elf; + Elf_Type type; + size_t count; + unsigned int version; +{ + /* We do not have differences between file and memory sizes. Better + not since otherwise `mmap' would not work. */ + if (elf == NULL) + return 0; + + if (version == EV_NONE || version >= EV_NUM) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return 0; + } + + if (type >= ELF_T_NUM) + { + __libelf_seterrno (ELF_E_UNKNOWN_TYPE); + return 0; + } + +#if EV_NUM != 2 + return count * __libelf_type_sizes[version - 1][elf->class - 1][type]; +#else + return count * __libelf_type_sizes[0][elf->class - 1][type]; +#endif +} +INTDEF(gelf_fsize) diff --git a/libelf/gelf_getauxv.c b/libelf/gelf_getauxv.c new file mode 100644 index 0000000..036bdcc --- /dev/null +++ b/libelf/gelf_getauxv.c @@ -0,0 +1,130 @@ +/* Get information from auxiliary vector at the given index. + Copyright (C) 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_auxv_t * +gelf_getauxv (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_auxv_t *dst; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + GElf_auxv_t *result = NULL; + Elf *elf; + + if (data_scn == NULL) + return NULL; + + if (unlikely (data_scn->d.d_type != ELF_T_AUXV)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + elf = data_scn->s->elf; + + rwlock_rdlock (elf->lock); + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (elf->class == ELFCLASS32) + { + Elf32_auxv_t *src; + + /* Here it gets a bit more complicated. The format of the vector + entries has to be converted. The user better have provided a + buffer where we can store the information. While copying the data + we convert the format. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ + dst->a_type = src->a_type; + dst->a_un.a_val = src->a_un.a_val; + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_auxv_t *) data_scn->d.d_buf)[ndx]; + } + + result = dst; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getclass.c b/libelf/gelf_getclass.c new file mode 100644 index 0000000..02784d7 --- /dev/null +++ b/libelf/gelf_getclass.c @@ -0,0 +1,66 @@ +/* Return the class of file associated with the descriptor. + Copyright (C) 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +int +gelf_getclass (elf) + Elf *elf; +{ + return elf == NULL || elf->kind != ELF_K_ELF ? ELFCLASSNONE : elf->class; +} diff --git a/libelf/gelf_getdyn.c b/libelf/gelf_getdyn.c new file mode 100644 index 0000000..82f8e32 --- /dev/null +++ b/libelf/gelf_getdyn.c @@ -0,0 +1,132 @@ +/* Get information from dynamic table at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Dyn * +gelf_getdyn (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Dyn *dst; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + GElf_Dyn *result = NULL; + Elf *elf; + + if (data_scn == NULL) + return NULL; + + if (unlikely (data_scn->d.d_type != ELF_T_DYN)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + elf = data_scn->s->elf; + + rwlock_rdlock (elf->lock); + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (elf->class == ELFCLASS32) + { + Elf32_Dyn *src; + + /* Here it gets a bit more complicated. The format of the symbol + table entries has to be adopted. The user better has provided + a buffer where we can store the information. While copying the + data we are converting the format. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ + dst->d_tag = src->d_tag; + /* It OK to copy `d_val' since `d_ptr' has the same size. */ + dst->d_un.d_val = src->d_un.d_val; + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_Dyn) == sizeof (Elf64_Dyn)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Dyn *) data_scn->d.d_buf)[ndx]; + } + + result = dst; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getehdr.c b/libelf/gelf_getehdr.c new file mode 100644 index 0000000..34b5db3 --- /dev/null +++ b/libelf/gelf_getehdr.c @@ -0,0 +1,132 @@ +/* Get ELF header. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Ehdr * +__gelf_getehdr_rdlock (elf, dest) + Elf *elf; + GElf_Ehdr *dest; +{ + GElf_Ehdr *result = NULL; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* The following is an optimization: the ehdr element is at the same + position in both the elf32 and elf64 structure. */ + if (offsetof (struct Elf, state.elf32.ehdr) + != offsetof (struct Elf, state.elf64.ehdr)) + abort (); + /* Just pick one of the values. */ + if (unlikely (elf->state.elf64.ehdr == NULL)) + /* Maybe no ELF header was created yet. */ + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + else if (elf->class == ELFCLASS32) + { + Elf32_Ehdr *ehdr = elf->state.elf32.ehdr; + + /* Convert the 32-bit struct to an 64-bit one. */ + memcpy (dest->e_ident, ehdr->e_ident, EI_NIDENT); +#define COPY(name) \ + dest->name = ehdr->name + COPY (e_type); + COPY (e_machine); + COPY (e_version); + COPY (e_entry); + COPY (e_phoff); + COPY (e_shoff); + COPY (e_flags); + COPY (e_ehsize); + COPY (e_phentsize); + COPY (e_phnum); + COPY (e_shentsize); + COPY (e_shnum); + COPY (e_shstrndx); + + result = dest; + } + else + result = memcpy (dest, elf->state.elf64.ehdr, sizeof (*dest)); + + return result; +} + +GElf_Ehdr * +gelf_getehdr (elf, dest) + Elf *elf; + GElf_Ehdr *dest; +{ + GElf_Ehdr *result; + if (elf == NULL) + return NULL; + + rwlock_rdlock (elf->lock); + result = __gelf_getehdr_rdlock (elf, dest); + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getlib.c b/libelf/gelf_getlib.c new file mode 100644 index 0000000..aa91a73 --- /dev/null +++ b/libelf/gelf_getlib.c @@ -0,0 +1,101 @@ +/* Get library from table at the given index. + Copyright (C) 2004 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Lib * +gelf_getlib (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Lib *dst; +{ + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_LIB)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + rwlock_rdlock (data_scn->s->elf->lock); + + /* The on disk format of Elf32_Lib and Elf64_Lib is identical. So + we can simplify things significantly. */ + assert (sizeof (GElf_Lib) == sizeof (Elf32_Lib)); + assert (sizeof (GElf_Lib) == sizeof (Elf64_Lib)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + GElf_Lib *result = NULL; + if (unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size)) + __libelf_seterrno (ELF_E_INVALID_INDEX); + else + { + *dst = ((GElf_Lib *) data->d_buf)[ndx]; + + result = dst; + } + + rwlock_unlock (data_scn->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getmove.c b/libelf/gelf_getmove.c new file mode 100644 index 0000000..6e76948 --- /dev/null +++ b/libelf/gelf_getmove.c @@ -0,0 +1,103 @@ +/* Get move structure at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +GElf_Move * +gelf_getmove (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Move *dst; +{ + GElf_Move *result = NULL; + Elf *elf; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_MOVE)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Move) == sizeof (Elf32_Move)); + assert (sizeof (GElf_Move) == sizeof (Elf64_Move)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + elf = ((Elf_Data_Scn *) data)->s->elf; + rwlock_rdlock (elf->lock); + + *dst = ((GElf_Move *) data->d_buf)[ndx]; + + rwlock_unlock (elf->lock); + + result = dst; + + out: + return result; +} diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c new file mode 100644 index 0000000..e490018 --- /dev/null +++ b/libelf/gelf_getnote.c @@ -0,0 +1,119 @@ +/* Get note information at the supplied offset. + Copyright (C) 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + +size_t +gelf_getnote (data, offset, result, name_offset, desc_offset) + Elf_Data *data; + size_t offset; + GElf_Nhdr *result; + size_t *name_offset; + size_t *desc_offset; +{ + if (data == NULL) + return 0; + + if (unlikely (data->d_type != ELF_T_NHDR)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Nhdr) == sizeof (Elf32_Nhdr)); + assert (sizeof (GElf_Nhdr) == sizeof (Elf64_Nhdr)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + offset is OK. */ + if (unlikely (offset + sizeof (GElf_Nhdr) > data->d_size)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + offset = 0; + } + else + { + const GElf_Nhdr *n = data->d_buf + offset; + offset += sizeof *n; + + GElf_Word namesz = NOTE_ALIGN (n->n_namesz); + GElf_Word descsz = NOTE_ALIGN (n->n_descsz); + + if (unlikely (data->d_size - offset < namesz)) + offset = 0; + else + { + *name_offset = offset; + offset += namesz; + if (unlikely (data->d_size - offset < descsz)) + offset = 0; + else + { + *desc_offset = offset; + offset += descsz; + *result = *n; + } + } + } + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return offset; +} diff --git a/libelf/gelf_getphdr.c b/libelf/gelf_getphdr.c new file mode 100644 index 0000000..7b04b39 --- /dev/null +++ b/libelf/gelf_getphdr.c @@ -0,0 +1,163 @@ +/* Return program header table entry. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> +#include <stdbool.h> + +#include "libelfP.h" + + +GElf_Phdr * +gelf_getphdr (elf, ndx, dst) + Elf *elf; + int ndx; + GElf_Phdr *dst; +{ + GElf_Phdr *result = NULL; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + if (dst == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + rwlock_rdlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + /* Copy the elements one-by-one. */ + Elf32_Phdr *phdr = elf->state.elf32.phdr; + + if (phdr == NULL) + { + rwlock_unlock (elf->lock); + phdr = INTUSE(elf32_getphdr) (elf); + if (phdr == NULL) + /* The error number is already set. */ + return NULL; + rwlock_rdlock (elf->lock); + } + + /* Test whether the index is ok. */ + size_t phnum; + if (ndx >= elf->state.elf32.ehdr->e_phnum + && (elf->state.elf32.ehdr->e_phnum != PN_XNUM + || __elf_getphdrnum_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* We know the result now. */ + result = dst; + + /* Now correct the pointer to point to the correct element. */ + phdr += ndx; + +#define COPY(Name) result->Name = phdr->Name + COPY (p_type); + COPY (p_offset); + COPY (p_vaddr); + COPY (p_paddr); + COPY (p_filesz); + COPY (p_memsz); + COPY (p_flags); + COPY (p_align); + } + else + { + /* Copy the elements one-by-one. */ + Elf64_Phdr *phdr = elf->state.elf64.phdr; + + if (phdr == NULL) + { + rwlock_unlock (elf->lock); + phdr = INTUSE(elf64_getphdr) (elf); + if (phdr == NULL) + /* The error number is already set. */ + return NULL; + rwlock_rdlock (elf->lock); + } + + /* Test whether the index is ok. */ + size_t phnum; + if (ndx >= elf->state.elf64.ehdr->e_phnum + && (elf->state.elf64.ehdr->e_phnum != PN_XNUM + || __elf_getphdrnum_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* We only have to copy the data. */ + result = memcpy (dst, phdr + ndx, sizeof (GElf_Phdr)); + } + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getrel.c b/libelf/gelf_getrel.c new file mode 100644 index 0000000..f3775bd --- /dev/null +++ b/libelf/gelf_getrel.c @@ -0,0 +1,129 @@ +/* Get REL relocation information at given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Rel * +gelf_getrel (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Rel *dst; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + GElf_Rel *result; + + if (data_scn == NULL) + return NULL; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return NULL; + } + + if (unlikely (data_scn->d.d_type != ELF_T_REL)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + scn = data_scn->s; + + rwlock_rdlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + /* We have to convert the data. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + { + Elf32_Rel *src = &((Elf32_Rel *) data_scn->d.d_buf)[ndx]; + + dst->r_offset = src->r_offset; + dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info), + ELF32_R_TYPE (src->r_info)); + + result = dst; + } + } + else + { + /* Simply copy the data after we made sure we are actually getting + correct data. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + result = memcpy (dst, &((Elf64_Rel *) data_scn->d.d_buf)[ndx], + sizeof (Elf64_Rel)); + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_getrela.c b/libelf/gelf_getrela.c new file mode 100644 index 0000000..0275c37 --- /dev/null +++ b/libelf/gelf_getrela.c @@ -0,0 +1,130 @@ +/* Get RELA relocation information at given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Rela * +gelf_getrela (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Rela *dst; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + GElf_Rela *result; + + if (data_scn == NULL) + return NULL; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return NULL; + } + + if (unlikely (data_scn->d.d_type != ELF_T_RELA)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + scn = data_scn->s; + + rwlock_rdlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + /* We have to convert the data. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + { + Elf32_Rela *src = &((Elf32_Rela *) data_scn->d.d_buf)[ndx]; + + dst->r_offset = src->r_offset; + dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info), + ELF32_R_TYPE (src->r_info)); + dst->r_addend = src->r_addend; + + result = dst; + } + } + else + { + /* Simply copy the data after we made sure we are actually getting + correct data. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + result = memcpy (dst, &((Elf64_Rela *) data_scn->d.d_buf)[ndx], + sizeof (Elf64_Rela)); + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_getshdr.c b/libelf/gelf_getshdr.c new file mode 100644 index 0000000..8b46dfa --- /dev/null +++ b/libelf/gelf_getshdr.c @@ -0,0 +1,126 @@ +/* Return section header. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Shdr * +gelf_getshdr (scn, dst) + Elf_Scn *scn; + GElf_Shdr *dst; +{ + GElf_Shdr *result = NULL; + + if (scn == NULL) + return NULL; + + if (dst == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + rwlock_rdlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + /* Copy the elements one-by-one. */ + Elf32_Shdr *shdr + = scn->shdr.e32 ?: __elf32_getshdr_rdlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + +#define COPY(name) \ + dst->name = shdr->name + COPY (sh_name); + COPY (sh_type); + COPY (sh_flags); + COPY (sh_addr); + COPY (sh_offset); + COPY (sh_size); + COPY (sh_link); + COPY (sh_info); + COPY (sh_addralign); + COPY (sh_entsize); + + result = dst; + } + else + { + Elf64_Shdr *shdr + = scn->shdr.e64 ?: __elf64_getshdr_rdlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + + /* We only have to copy the data. */ + result = memcpy (dst, shdr, sizeof (GElf_Shdr)); + } + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} +INTDEF(gelf_getshdr) diff --git a/libelf/gelf_getsym.c b/libelf/gelf_getsym.c new file mode 100644 index 0000000..162061f --- /dev/null +++ b/libelf/gelf_getsym.c @@ -0,0 +1,138 @@ +/* Get symbol information from symbol table at the given index. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Sym * +gelf_getsym (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Sym *dst; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + GElf_Sym *result = NULL; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_SYM)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (data_scn->s->elf->lock); + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (data_scn->s->elf->class == ELFCLASS32) + { + Elf32_Sym *src; + + /* Here it gets a bit more complicated. The format of the symbol + table entries has to be adopted. The user better has provided + a buffer where we can store the information. While copying the + data we are converting the format. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_Sym *) data->d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ +#define COPY(name) \ + dst->name = src->name + COPY (st_name); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + COPY (st_value); + COPY (st_size); + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Sym *) data->d_buf)[ndx]; + } + + result = dst; + + out: + rwlock_unlock (data_scn->s->elf->lock); + + return result; +} +INTDEF(gelf_getsym) diff --git a/libelf/gelf_getsyminfo.c b/libelf/gelf_getsyminfo.c new file mode 100644 index 0000000..2c07526 --- /dev/null +++ b/libelf/gelf_getsyminfo.c @@ -0,0 +1,101 @@ +/* Get additional symbol information from symbol table at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Syminfo * +gelf_getsyminfo (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Syminfo *dst; +{ + GElf_Syminfo *result = NULL; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_SYMINFO)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo)); + assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Syminfo *) data->d_buf)[ndx]; + + result = dst; + + out: + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getsymshndx.c b/libelf/gelf_getsymshndx.c new file mode 100644 index 0000000..a9cfc18 --- /dev/null +++ b/libelf/gelf_getsymshndx.c @@ -0,0 +1,161 @@ +/* Get symbol information and separate section index from symbol table + at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Sym * +gelf_getsymshndx (symdata, shndxdata, ndx, dst, dstshndx) + Elf_Data *symdata; + Elf_Data *shndxdata; + int ndx; + GElf_Sym *dst; + Elf32_Word *dstshndx; +{ + Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata; + Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata; + GElf_Sym *result = NULL; + Elf32_Word shndx = 0; + + if (symdata == NULL) + return NULL; + + if (unlikely (symdata->d_type != ELF_T_SYM) + || (likely (shndxdata_scn != NULL) + && unlikely (shndxdata->d_type != ELF_T_WORD))) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (symdata_scn->s->elf->lock); + + /* The user is not required to pass a data descriptor for an extended + section index table. */ + if (likely (shndxdata_scn != NULL)) + { + if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + shndx = ((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx]; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (symdata_scn->s->elf->class == ELFCLASS32) + { + Elf32_Sym *src; + + /* Here it gets a bit more complicated. The format of the symbol + table entries has to be adopted. The user better has provided + a buffer where we can store the information. While copying the + data we are converting the format. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata->d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_Sym *) symdata->d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ +#define COPY(name) \ + dst->name = src->name + COPY (st_name); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + COPY (st_value); + COPY (st_size); + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > symdata->d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Sym *) symdata->d_buf)[ndx]; + } + + /* Now we can store the section index. */ + if (dstshndx != NULL) + *dstshndx = shndx; + + result = dst; + + out: + rwlock_unlock (symdata_scn->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getverdaux.c b/libelf/gelf_getverdaux.c new file mode 100644 index 0000000..b8bcf14 --- /dev/null +++ b/libelf/gelf_getverdaux.c @@ -0,0 +1,103 @@ +/* Get additional symbol version definition information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Verdaux * +gelf_getverdaux (data, offset, dst) + Elf_Data *data; + int offset; + GElf_Verdaux *dst; +{ + GElf_Verdaux *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VDEF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Verdaux) > data->d_size) + || unlikely (offset % __alignof__ (GElf_Verdaux) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Verdaux *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verdaux)); + + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getverdef.c b/libelf/gelf_getverdef.c new file mode 100644 index 0000000..05cc2e8 --- /dev/null +++ b/libelf/gelf_getverdef.c @@ -0,0 +1,102 @@ +/* Get symbol version definition information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Verdef * +gelf_getverdef (data, offset, dst) + Elf_Data *data; + int offset; + GElf_Verdef *dst; +{ + GElf_Verdef *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VDEF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef)); + assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Verdef) > data->d_size) + || unlikely (offset % __alignof__ (GElf_Verdef) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Verdef *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verdef)); + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getvernaux.c b/libelf/gelf_getvernaux.c new file mode 100644 index 0000000..45d3300 --- /dev/null +++ b/libelf/gelf_getvernaux.c @@ -0,0 +1,105 @@ +/* Get additional required symbol version information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Vernaux * +gelf_getvernaux (data, offset, dst) + Elf_Data *data; + int offset; + GElf_Vernaux *dst; +{ + GElf_Vernaux *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VNEED)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. And fortunately the `ElfXXX_Vernaux' records + also have the same size. */ + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Vernaux) > data->d_size) + || unlikely (offset % sizeof (GElf_Vernaux) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Vernaux *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verneed)); + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getverneed.c b/libelf/gelf_getverneed.c new file mode 100644 index 0000000..e82a055 --- /dev/null +++ b/libelf/gelf_getverneed.c @@ -0,0 +1,105 @@ +/* Get required symbol version information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Verneed * +gelf_getverneed (data, offset, dst) + Elf_Data *data; + int offset; + GElf_Verneed *dst; +{ + GElf_Verneed *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VNEED)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. And fortunately the `ElfXXX_Vernaux' records + also have the same size. */ + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed)); + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Vernaux)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Verneed) > data->d_size) + || unlikely (offset % sizeof (GElf_Verneed) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Verneed *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verneed)); + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getversym.c b/libelf/gelf_getversym.c new file mode 100644 index 0000000..397b7ed --- /dev/null +++ b/libelf/gelf_getversym.c @@ -0,0 +1,110 @@ +/* Get symbol version information at the given index. + Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1999. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +GElf_Versym * +gelf_getversym (data, ndx, dst) + Elf_Data *data; + int ndx; + GElf_Versym *dst; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + GElf_Versym *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_HALF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + scn = data_scn->s; + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym)); + assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym)); + + rwlock_rdlock (scn->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + { + *dst = ((GElf_Versym *) data->d_buf)[ndx]; + + result = dst; + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_newehdr.c b/libelf/gelf_newehdr.c new file mode 100644 index 0000000..2f720b8 --- /dev/null +++ b/libelf/gelf_newehdr.c @@ -0,0 +1,69 @@ +/* Create new ELF header. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +unsigned long int +gelf_newehdr (elf, class) + Elf *elf; + int class; +{ + return (class == ELFCLASS32 + ? (unsigned long int) INTUSE(elf32_newehdr) (elf) + : (unsigned long int) INTUSE(elf64_newehdr) (elf)); +} diff --git a/libelf/gelf_newphdr.c b/libelf/gelf_newphdr.c new file mode 100644 index 0000000..6530692 --- /dev/null +++ b/libelf/gelf_newphdr.c @@ -0,0 +1,69 @@ +/* Create new ELF program header. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +unsigned long int +gelf_newphdr (elf, phnum) + Elf *elf; + size_t phnum; +{ + return (elf->class == ELFCLASS32 + ? (unsigned long int) INTUSE(elf32_newphdr) (elf, phnum) + : (unsigned long int) INTUSE(elf64_newphdr) (elf, phnum)); +} diff --git a/libelf/gelf_offscn.c b/libelf/gelf_offscn.c new file mode 100644 index 0000000..573195c --- /dev/null +++ b/libelf/gelf_offscn.c @@ -0,0 +1,78 @@ +/* Create new ELF header. + Copyright (C) 2005 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2005. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +Elf_Scn * +gelf_offscn (elf, offset) + Elf *elf; + GElf_Off offset; +{ + if (elf->class == ELFCLASS32) + { + if ((Elf32_Off) offset != offset) + { + __libelf_seterrno (ELF_E_INVALID_OFFSET); + return NULL; + } + + return INTUSE(elf32_offscn) (elf, (Elf32_Off) offset); + } + + return INTUSE(elf64_offscn) (elf, offset); +} diff --git a/libelf/gelf_update_auxv.c b/libelf/gelf_update_auxv.c new file mode 100644 index 0000000..b294ead --- /dev/null +++ b/libelf/gelf_update_auxv.c @@ -0,0 +1,135 @@ +/* Update information in dynamic table at the given index. + Copyright (C) 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_auxv (data, ndx, src) + Elf_Data *data; + int ndx; + GElf_auxv_t *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_AUXV)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_auxv_t *auxv; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->a_type > 0xffffffffll) + || unlikely (src->a_un.a_val > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + auxv = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx]; + + auxv->a_type = src->a_type; + auxv->a_un.a_val = src->a_un.a_val; + } + else + { + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_auxv_t *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_dyn.c b/libelf/gelf_update_dyn.c new file mode 100644 index 0000000..10bfb6a --- /dev/null +++ b/libelf/gelf_update_dyn.c @@ -0,0 +1,137 @@ +/* Update information in dynamic table at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_dyn (data, ndx, src) + Elf_Data *data; + int ndx; + GElf_Dyn *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_DYN)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Dyn *dyn; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->d_tag < -0x80000000ll) + || unlikely (src->d_tag > 0x7fffffffll) + || unlikely (src->d_un.d_val > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + dyn = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx]; + + dyn->d_tag = src->d_tag; + dyn->d_un.d_val = src->d_un.d_val; + } + else + { + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_Dyn) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Dyn *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_ehdr.c b/libelf/gelf_update_ehdr.c new file mode 100644 index 0000000..baf7a3f --- /dev/null +++ b/libelf/gelf_update_ehdr.c @@ -0,0 +1,139 @@ +/* Update ELF header. + Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_ehdr (Elf *elf, GElf_Ehdr *src) +{ + int result = 0; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + Elf32_Ehdr *ehdr = elf->state.elf32.ehdr; + + if (ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + goto out; + } + + /* We have to convert the data to the 32 bit format. This might + overflow some fields so we have to test for this case before + copying. */ + if (unlikely (src->e_entry > 0xffffffffull) + || unlikely (src->e_phoff > 0xffffffffull) + || unlikely (src->e_shoff > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Copy the data. */ + memcpy (ehdr->e_ident, src->e_ident, EI_NIDENT); +#define COPY(name) \ + ehdr->name = src->name + COPY (e_type); + COPY (e_machine); + COPY (e_version); + COPY (e_entry); + COPY (e_phoff); + COPY (e_shoff); + COPY (e_flags); + COPY (e_ehsize); + COPY (e_phentsize); + COPY (e_phnum); + COPY (e_shentsize); + COPY (e_shnum); + COPY (e_shstrndx); + } + else + { + Elf64_Ehdr *ehdr = elf->state.elf64.ehdr; + + if (ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + goto out; + } + + /* Just copy the data. */ + memcpy (ehdr, src, sizeof (Elf64_Ehdr)); + } + + /* Mark the ELF header as modified. */ + elf->state.elf.ehdr_flags |= ELF_F_DIRTY; + + result = 1; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_update_lib.c b/libelf/gelf_update_lib.c new file mode 100644 index 0000000..9571016 --- /dev/null +++ b/libelf/gelf_update_lib.c @@ -0,0 +1,105 @@ +/* Update library in table at the given index. + Copyright (C) 2004 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_lib (data, ndx, src) + Elf_Data *data; + int ndx; + GElf_Lib *src; +{ + if (data == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + if (unlikely (data_scn->d.d_type != ELF_T_LIB)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + Elf_Scn *scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + /* Check whether we have to resize the data buffer. */ + int result = 0; + if (unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size)) + __libelf_seterrno (ELF_E_INVALID_INDEX); + else + { + ((Elf64_Lib *) data_scn->d.d_buf)[ndx] = *src; + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_move.c b/libelf/gelf_update_move.c new file mode 100644 index 0000000..fd67be1 --- /dev/null +++ b/libelf/gelf_update_move.c @@ -0,0 +1,102 @@ +/* Update move structure at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +int +gelf_update_move (data, ndx, src) + Elf_Data *data; + int ndx; + GElf_Move *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Move) == sizeof (Elf32_Move)); + assert (sizeof (GElf_Move) == sizeof (Elf64_Move)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (ndx < 0) + || unlikely ((ndx + 1) * sizeof (GElf_Move) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_MOVE)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + ((GElf_Move *) data_scn->d.d_buf)[ndx] = *src; + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_phdr.c b/libelf/gelf_update_phdr.c new file mode 100644 index 0000000..b90e5c0 --- /dev/null +++ b/libelf/gelf_update_phdr.c @@ -0,0 +1,164 @@ +/* Update program header program header table entry. + Copyright (C) 2000-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src) +{ + int result = 0; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + Elf32_Phdr *phdr = elf->state.elf32.phdr; + + /* We have to convert the data to the 32 bit format. This might + overflow some fields so we have to test for this case before + copying. */ + if (unlikely (src->p_offset > 0xffffffffull) + || unlikely (src->p_vaddr > 0xffffffffull) + || unlikely (src->p_paddr > 0xffffffffull) + || unlikely (src->p_filesz > 0xffffffffull) + || unlikely (src->p_memsz > 0xffffffffull) + || unlikely (src->p_align > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + if (phdr == NULL) + { + phdr = __elf32_getphdr_wrlock (elf); + if (phdr == NULL) + /* The error number is already set. */ + goto out; + } + + /* Test whether the index is ok. */ + size_t phnum; + if (ndx >= elf->state.elf32.ehdr->e_phnum + && (elf->state.elf32.ehdr->e_phnum != PN_XNUM + || __elf_getphdrnum_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* Now correct the pointer to point to the correct element. */ + phdr += ndx; + +#define COPY(name) \ + phdr->name = src->name + COPY (p_type); + COPY (p_offset); + COPY (p_vaddr); + COPY (p_paddr); + COPY (p_filesz); + COPY (p_memsz); + COPY (p_flags); + COPY (p_align); + } + else + { + Elf64_Phdr *phdr = elf->state.elf64.phdr; + + if (phdr == NULL) + { + phdr = __elf64_getphdr_wrlock (elf); + if (phdr == NULL) + /* The error number is already set. */ + goto out; + } + + /* Test whether the index is ok. */ + size_t phnum; + if (ndx >= elf->state.elf64.ehdr->e_phnum + && (elf->state.elf64.ehdr->e_phnum != PN_XNUM + || __elf_getphdrnum_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* Just copy the data. */ + memcpy (phdr + ndx, src, sizeof (Elf64_Phdr)); + } + + /* Mark the program header as modified. */ + elf->state.elf.phdr_flags |= ELF_F_DIRTY; + + result = 1; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_update_rel.c b/libelf/gelf_update_rel.c new file mode 100644 index 0000000..049b71a --- /dev/null +++ b/libelf/gelf_update_rel.c @@ -0,0 +1,135 @@ +/* Update REL relocation information at given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +int +gelf_update_rel (Elf_Data *dst, int ndx, GElf_Rel *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst; + Elf_Scn *scn; + int result = 0; + + if (dst == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_REL)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Rel *rel; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->r_offset > 0xffffffffull) + || unlikely (GELF_R_SYM (src->r_info) > 0xffffff) + || unlikely (GELF_R_TYPE (src->r_info) > 0xff)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + rel = &((Elf32_Rel *) data_scn->d.d_buf)[ndx]; + + rel->r_offset = src->r_offset; + rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), + GELF_R_TYPE (src->r_info)); + } + else + { + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Rel *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_rela.c b/libelf/gelf_update_rela.c new file mode 100644 index 0000000..dc99c68 --- /dev/null +++ b/libelf/gelf_update_rela.c @@ -0,0 +1,138 @@ +/* Update RELA relocation information at given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +int +gelf_update_rela (Elf_Data *dst, int ndx, GElf_Rela *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst; + Elf_Scn *scn; + int result = 0; + + if (dst == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_RELA)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Rela *rel; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->r_offset > 0xffffffffull) + || unlikely (GELF_R_SYM (src->r_info) > 0xffffff) + || unlikely (GELF_R_TYPE (src->r_info) > 0xff) + || unlikely (src->r_addend < -0x80000000ll) + || unlikely (src->r_addend > 0x7fffffffll)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + rel = &((Elf32_Rela *) data_scn->d.d_buf)[ndx]; + + rel->r_offset = src->r_offset; + rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), + GELF_R_TYPE (src->r_info)); + rel->r_addend = src->r_addend; + } + else + { + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Rela *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_shdr.c b/libelf/gelf_update_shdr.c new file mode 100644 index 0000000..c4e3829 --- /dev/null +++ b/libelf/gelf_update_shdr.c @@ -0,0 +1,132 @@ +/* Update section header. + Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_shdr (Elf_Scn *scn, GElf_Shdr *src) +{ + int result = 0; + Elf *elf; + + if (scn == NULL || src == NULL) + return 0; + + elf = scn->elf; + rwlock_wrlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + Elf32_Shdr *shdr + = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + + if (unlikely (src->sh_flags > 0xffffffffull) + || unlikely (src->sh_addr > 0xffffffffull) + || unlikely (src->sh_offset > 0xffffffffull) + || unlikely (src->sh_size > 0xffffffffull) + || unlikely (src->sh_addralign > 0xffffffffull) + || unlikely (src->sh_entsize > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + +#define COPY(name) \ + shdr->name = src->name + COPY (sh_name); + COPY (sh_type); + COPY (sh_flags); + COPY (sh_addr); + COPY (sh_offset); + COPY (sh_size); + COPY (sh_link); + COPY (sh_info); + COPY (sh_addralign); + COPY (sh_entsize); + } + else + { + Elf64_Shdr *shdr + = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + + /* We only have to copy the data. */ + (void) memcpy (shdr, src, sizeof (GElf_Shdr)); + } + + /* Mark the section header as modified. */ + scn->shdr_flags |= ELF_F_DIRTY; + + result = 1; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_update_sym.c b/libelf/gelf_update_sym.c new file mode 100644 index 0000000..fff45fd --- /dev/null +++ b/libelf/gelf_update_sym.c @@ -0,0 +1,146 @@ +/* Update symbol information in symbol table at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_sym (data, ndx, src) + Elf_Data *data; + int ndx; + GElf_Sym *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_SYM)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Sym *sym; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->st_value > 0xffffffffull) + || unlikely (src->st_size > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + sym = &((Elf32_Sym *) data_scn->d.d_buf)[ndx]; + +#define COPY(name) \ + sym->name = src->name + COPY (st_name); + COPY (st_value); + COPY (st_size); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + } + else + { + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Sym *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_syminfo.c b/libelf/gelf_update_syminfo.c new file mode 100644 index 0000000..a0e176d --- /dev/null +++ b/libelf/gelf_update_syminfo.c @@ -0,0 +1,113 @@ +/* Update additional symbol information in symbol table at the given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +int +gelf_update_syminfo (data, ndx, src) + Elf_Data *data; + int ndx; + GElf_Syminfo *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo)); + assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo)); + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((GElf_Syminfo *) data_scn->d.d_buf)[ndx] = *src; + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_symshndx.c b/libelf/gelf_update_symshndx.c new file mode 100644 index 0000000..2d393c1 --- /dev/null +++ b/libelf/gelf_update_symshndx.c @@ -0,0 +1,176 @@ +/* Update symbol information and section index in symbol table at the + given index. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stdlib.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_symshndx (symdata, shndxdata, ndx, src, srcshndx) + Elf_Data *symdata; + Elf_Data *shndxdata; + int ndx; + GElf_Sym *src; + Elf32_Word srcshndx; +{ + Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata; + Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata; + Elf_Scn *scn; + Elf32_Word *shndx = NULL; + int result = 0; + + if (symdata == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (symdata_scn->d.d_type != ELF_T_SYM)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = symdata_scn->s; + /* We simply have to believe the user that the two sections belong to + the same ELF file. */ + rwlock_wrlock (scn->elf->lock); + + /* The user is not required to pass a data descriptor for an extended + section index table. */ + if (shndxdata_scn != NULL) + { + if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + shndx = &((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx]; + } + /* But if s/he does not the extended sectio index must be zero. */ + else if (unlikely (srcshndx != 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Sym *sym; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->st_value > 0xffffffffull) + || unlikely (src->st_size > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + sym = &((Elf32_Sym *) symdata_scn->d.d_buf)[ndx]; + +#define COPY(name) \ + sym->name = src->name + COPY (st_name); + COPY (st_value); + COPY (st_size); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + } + else + { + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Sym *) symdata_scn->d.d_buf)[ndx] = *src; + } + + /* Now we can store the section index. */ + if (shndx != NULL) + *shndx = srcshndx; + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_verdaux.c b/libelf/gelf_update_verdaux.c new file mode 100644 index 0000000..17866ef --- /dev/null +++ b/libelf/gelf_update_verdaux.c @@ -0,0 +1,102 @@ +/* Update additional symbol version definition information. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_verdaux (data, offset, src) + Elf_Data *data; + int offset; + GElf_Verdaux *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Verdaux)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VDEF)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdaux)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_verdef.c b/libelf/gelf_update_verdef.c new file mode 100644 index 0000000..cd19cb7 --- /dev/null +++ b/libelf/gelf_update_verdef.c @@ -0,0 +1,102 @@ +/* Update symbol version definition information. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_verdef (data, offset, src) + Elf_Data *data; + int offset; + GElf_Verdef *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef)); + assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Verdef)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VDEF)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdef)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_vernaux.c b/libelf/gelf_update_vernaux.c new file mode 100644 index 0000000..2be69e1 --- /dev/null +++ b/libelf/gelf_update_vernaux.c @@ -0,0 +1,102 @@ +/* Update additional required symbol version information. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_vernaux (data, offset, src) + Elf_Data *data; + int offset; + GElf_Vernaux *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Vernaux)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VNEED)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Vernaux)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_verneed.c b/libelf/gelf_update_verneed.c new file mode 100644 index 0000000..95f2d18 --- /dev/null +++ b/libelf/gelf_update_verneed.c @@ -0,0 +1,102 @@ +/* Update required symbol version information. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <string.h> + +#include "libelfP.h" + + +int +gelf_update_verneed (data, offset, src) + Elf_Data *data; + int offset; + GElf_Verneed *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Verneed)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VNEED)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verneed)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_versym.c b/libelf/gelf_update_versym.c new file mode 100644 index 0000000..905c8f7 --- /dev/null +++ b/libelf/gelf_update_versym.c @@ -0,0 +1,102 @@ +/* Update symbol version information. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2001. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <gelf.h> +#include <stdlib.h> + +#include "libelfP.h" + + +int +gelf_update_versym (data, ndx, src) + Elf_Data *data; + int ndx; + GElf_Versym *src; +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym)); + assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (ndx < 0) + || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_HALF)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + ((GElf_Versym *) data_scn->d.d_buf)[ndx] = *src; + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c new file mode 100644 index 0000000..a4134c3 --- /dev/null +++ b/libelf/gelf_xlate.c @@ -0,0 +1,235 @@ +/* Transformation functions for ELF data types. + Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <byteswap.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +/* Well, what shall I say. Nothing to do here. */ +#define elf_cvt_Byte(dest, src, n) \ + (__builtin_constant_p (n) && (n) == 1 \ + ? (void) (*((char *) (dest)) = *((char *) (src))) \ + : Elf32_cvt_Byte (dest, src, n)) +static void +(elf_cvt_Byte) (void *dest, const void *src, size_t n, + int encode __attribute__ ((unused))) +{ + memmove (dest, src, n); +} + + +/* We'll optimize the definition of the conversion functions here a + bit. We need only functions for 16, 32, and 64 bits. The + functions referenced in the table will be aliases for one of these + functions. Which one is decided by the ELFxx_FSZ_type. */ + +#if ALLOW_UNALIGNED + +#define FETCH(Bits, ptr) (*(const uint##Bits##_t *) ptr) +#define STORE(Bits, ptr, val) (*(uint##Bits##_t *) ptr = val) + +#else + +union unaligned + { + uint16_t u16; + uint32_t u32; + uint64_t u64; + } __attribute__ ((packed)); + +#define FETCH(Bits, ptr) (((const union unaligned *) ptr)->u##Bits) +#define STORE(Bits, ptr, val) (((union unaligned *) ptr)->u##Bits = val) + +#endif + +/* Now define the conversion functions for the basic types. We use here + the fact that file and memory types are the same and that we have the + ELFxx_FSZ_* macros. + + At the same time we define inline functions which we will use to + convert the complex types. */ +#define FUNDAMENTAL(NAME, Name, Bits) \ + INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name)) +#define INLINE2(Bytes, FName, TName) \ + INLINE3 (Bytes, FName, TName) +#define INLINE3(Bytes, FName, TName) \ + static inline void FName##1 (void *dest, const void *ptr) \ + { \ + switch (Bytes) \ + { \ + case 2: STORE (16, dest, bswap_16 (FETCH (16, ptr))); break; \ + case 4: STORE (32, dest, bswap_32 (FETCH (32, ptr))); break; \ + case 8: STORE (64, dest, bswap_64 (FETCH (64, ptr))); break; \ + default: \ + abort (); \ + } \ + } \ + \ + static void FName (void *dest, const void *ptr, size_t len, \ + int encode __attribute__ ((unused))) \ + { \ + size_t n = len / sizeof (TName); \ + if (dest < ptr) \ + while (n-- > 0) \ + { \ + FName##1 (dest, ptr); \ + dest += Bytes; \ + ptr += Bytes; \ + } \ + else \ + { \ + dest += len; \ + ptr += len; \ + while (n-- > 0) \ + { \ + ptr -= Bytes; \ + dest -= Bytes; \ + FName##1 (dest, ptr); \ + } \ + } \ + } + + +/* Now the tricky part: define the transformation functions for the + complex types. We will use the definitions of the types in + abstract.h. */ +#define START(Bits, Name, EName) \ + static void \ + ElfW2 (Bits, cvt_##Name) (void *dest, const void *src, size_t len, \ + int encode __attribute__ ((unused))) \ + { ElfW2(Bits, Name) *tdest = (ElfW2(Bits, Name) *) dest; \ + ElfW2(Bits, Name) *tsrc = (ElfW2(Bits, Name) *) src; \ + size_t n; \ + for (n = len / sizeof (ElfW2(Bits, Name)); n > 0; ++tdest, ++tsrc, --n) { +#define END(Bits, Name) } } +#define TYPE_EXTRA(Code) +#define TYPE_XLATE(Code) Code +#define TYPE_NAME(Type, Name) TYPE_NAME2 (Type, Name) +#define TYPE_NAME2(Type, Name) Type##1 (&tdest->Name, &tsrc->Name); +#define TYPE(Name, Bits) TYPE2 (Name, Bits) +#define TYPE2(Name, Bits) TYPE3 (Name##Bits) +#define TYPE3(Name) Name (cvt_) + +/* Signal that we are generating conversion functions. */ +#define GENERATE_CONVERSION + +/* First generate the 32-bit conversion functions. */ +#define LIBELFBITS 32 +#include "gelf_xlate.h" + +/* Now generate the 64-bit conversion functions. */ +#define LIBELFBITS 64 +#include "gelf_xlate.h" + + +/* We have a few functions which we must create by hand since the sections + do not contain records of only one type. */ +#include "version_xlate.h" +#include "gnuhash_xlate.h" +#include "note_xlate.h" + + +/* Now the externally visible table with the function pointers. */ +const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] = +{ + [EV_CURRENT - 1] = { + [EV_CURRENT - 1] = { + [ELFCLASS32 - 1] = { +#define define_xfcts(Bits) \ + [ELF_T_BYTE] = elf_cvt_Byte, \ + [ELF_T_ADDR] = ElfW2(Bits, cvt_Addr), \ + [ELF_T_DYN] = ElfW2(Bits, cvt_Dyn), \ + [ELF_T_EHDR] = ElfW2(Bits, cvt_Ehdr), \ + [ELF_T_HALF] = ElfW2(Bits, cvt_Half), \ + [ELF_T_OFF] = ElfW2(Bits, cvt_Off), \ + [ELF_T_PHDR] = ElfW2(Bits, cvt_Phdr), \ + [ELF_T_RELA] = ElfW2(Bits, cvt_Rela), \ + [ELF_T_REL] = ElfW2(Bits, cvt_Rel), \ + [ELF_T_SHDR] = ElfW2(Bits, cvt_Shdr), \ + [ELF_T_SWORD] = ElfW2(Bits, cvt_Sword), \ + [ELF_T_SYM] = ElfW2(Bits, cvt_Sym), \ + [ELF_T_WORD] = ElfW2(Bits, cvt_Word), \ + [ELF_T_XWORD] = ElfW2(Bits, cvt_Xword), \ + [ELF_T_SXWORD] = ElfW2(Bits, cvt_Sxword), \ + [ELF_T_VDEF] = elf_cvt_Verdef, \ + [ELF_T_VDAUX] = elf_cvt_Verdef, \ + [ELF_T_VNEED] = elf_cvt_Verneed, \ + [ELF_T_VNAUX] = elf_cvt_Verneed, \ + [ELF_T_NHDR] = elf_cvt_note, \ + [ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo), \ + [ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \ + [ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \ + [ELF_T_AUXV] = ElfW2(Bits, cvt_auxv_t) + define_xfcts (32), + [ELF_T_GNUHASH] = Elf32_cvt_Word + }, + [ELFCLASS64 - 1] = { + define_xfcts (64), + [ELF_T_GNUHASH] = elf_cvt_gnuhash + } + } + } +}; +/* For now we only handle the case where the memory representation is the + same as the file representation. Should this change we have to define + separate functions. For now reuse them. */ +strong_alias (__elf_xfctstom, __elf_xfctstof) diff --git a/libelf/gelf_xlate.h b/libelf/gelf_xlate.h new file mode 100644 index 0000000..e7659f1 --- /dev/null +++ b/libelf/gelf_xlate.h @@ -0,0 +1,77 @@ +/* Helper file for type conversion function generation. + Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + + +/* Simple types. */ +FUNDAMENTAL (ADDR, Addr, LIBELFBITS); +FUNDAMENTAL (OFF, Off, LIBELFBITS); +FUNDAMENTAL (HALF, Half, LIBELFBITS); +FUNDAMENTAL (WORD, Word, LIBELFBITS); +FUNDAMENTAL (SWORD, Sword, LIBELFBITS); +FUNDAMENTAL (XWORD, Xword, LIBELFBITS); +FUNDAMENTAL (SXWORD, Sxword, LIBELFBITS); + +/* The structured types. */ +TYPE (Ehdr, LIBELFBITS) +TYPE (Phdr, LIBELFBITS) +TYPE (Shdr, LIBELFBITS) +TYPE (Sym, LIBELFBITS) +TYPE (Rel, LIBELFBITS) +TYPE (Rela, LIBELFBITS) +TYPE (Note, LIBELFBITS) +TYPE (Dyn, LIBELFBITS) +TYPE (Syminfo, LIBELFBITS) +TYPE (Move, LIBELFBITS) +TYPE (Lib, LIBELFBITS) +TYPE (auxv_t, LIBELFBITS) + + +/* Prepare for the next round. */ +#undef LIBELFBITS diff --git a/libelf/gelf_xlatetof.c b/libelf/gelf_xlatetof.c new file mode 100644 index 0000000..e7f8238 --- /dev/null +++ b/libelf/gelf_xlatetof.c @@ -0,0 +1,74 @@ +/* Convert from memory to file representation. Generic ELF version. + Copyright (C) 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +Elf_Data * +gelf_xlatetof (elf, dest, src, encode) + Elf *elf; + Elf_Data *dest; + const Elf_Data * src; + unsigned int encode; +{ + if (elf == NULL) + return NULL; + + return (elf->class == ELFCLASS32 + ? INTUSE(elf32_xlatetof) (dest, src, encode) + : INTUSE(elf64_xlatetof) (dest, src, encode)); +} diff --git a/libelf/gelf_xlatetom.c b/libelf/gelf_xlatetom.c new file mode 100644 index 0000000..b7da1b2 --- /dev/null +++ b/libelf/gelf_xlatetom.c @@ -0,0 +1,74 @@ +/* Convert from file to memory representation. Generic ELF version. + Copyright (C) 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2000. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gelf.h> +#include <stddef.h> + +#include "libelfP.h" + + +Elf_Data * +gelf_xlatetom (elf, dest, src, encode) + Elf *elf; + Elf_Data *dest; + const Elf_Data * src; + unsigned int encode; +{ + if (elf == NULL) + return NULL; + + return (elf->class == ELFCLASS32 + ? INTUSE(elf32_xlatetom) (dest, src, encode) + : INTUSE(elf64_xlatetom) (dest, src, encode)); +} diff --git a/libelf/gnuhash_xlate.h b/libelf/gnuhash_xlate.h new file mode 100644 index 0000000..d79764d --- /dev/null +++ b/libelf/gnuhash_xlate.h @@ -0,0 +1,95 @@ +/* Conversion functions for versioning information. + Copyright (C) 2006, 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2006. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#include <assert.h> +#include <gelf.h> + +#include "libelfP.h" + + +static void +elf_cvt_gnuhash (void *dest, const void *src, size_t len, int encode) +{ + /* The GNU hash table format on 64 bit machines mixes 32 bit and 64 bit + words. We must detangle them here. */ + Elf32_Word *dest32 = dest; + const Elf32_Word *src32 = src; + + /* First four control words, 32 bits. */ + for (unsigned int cnt = 0; cnt < 4; ++cnt) + { + if (len < 4) + return; + dest32[cnt] = bswap_32 (src32[cnt]); + len -= 4; + } + + Elf32_Word bitmask_words = encode ? src32[2] : dest32[2]; + + /* Now the 64 bit words. */ + Elf64_Xword *dest64 = (Elf64_Xword *) &dest32[4]; + const Elf64_Xword *src64 = (const Elf64_Xword *) &src32[4]; + for (unsigned int cnt = 0; cnt < bitmask_words; ++cnt) + { + if (len < 8) + return; + dest64[cnt] = bswap_64 (src64[cnt]); + len -= 8; + } + + /* The rest are 32 bit words again. */ + src32 = (const Elf32_Word *) &src64[bitmask_words]; + dest32 = (Elf32_Word *) &dest64[bitmask_words]; + while (len >= 4) + { + *dest32++ = bswap_32 (*src32++); + len -= 4; + } +} diff --git a/libelf/libelf.h b/libelf/libelf.h new file mode 100644 index 0000000..b0b3a8d --- /dev/null +++ b/libelf/libelf.h @@ -0,0 +1,417 @@ +/* Interface for libelf. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _LIBELF_H +#define _LIBELF_H 1 + +#include <sys/types.h> + +/* Get the ELF types. */ +#include <elf.h> + + +/* Known translation types. */ +typedef enum +{ + ELF_T_BYTE, /* unsigned char */ + ELF_T_ADDR, /* Elf32_Addr, Elf64_Addr, ... */ + ELF_T_DYN, /* Dynamic section record. */ + ELF_T_EHDR, /* ELF header. */ + ELF_T_HALF, /* Elf32_Half, Elf64_Half, ... */ + ELF_T_OFF, /* Elf32_Off, Elf64_Off, ... */ + ELF_T_PHDR, /* Program header. */ + ELF_T_RELA, /* Relocation entry with addend. */ + ELF_T_REL, /* Relocation entry. */ + ELF_T_SHDR, /* Section header. */ + ELF_T_SWORD, /* Elf32_Sword, Elf64_Sword, ... */ + ELF_T_SYM, /* Symbol record. */ + ELF_T_WORD, /* Elf32_Word, Elf64_Word, ... */ + ELF_T_XWORD, /* Elf32_Xword, Elf64_Xword, ... */ + ELF_T_SXWORD, /* Elf32_Sxword, Elf64_Sxword, ... */ + ELF_T_VDEF, /* Elf32_Verdef, Elf64_Verdef, ... */ + ELF_T_VDAUX, /* Elf32_Verdaux, Elf64_Verdaux, ... */ + ELF_T_VNEED, /* Elf32_Verneed, Elf64_Verneed, ... */ + ELF_T_VNAUX, /* Elf32_Vernaux, Elf64_Vernaux, ... */ + ELF_T_NHDR, /* Elf32_Nhdr, Elf64_Nhdr, ... */ + ELF_T_SYMINFO, /* Elf32_Syminfo, Elf64_Syminfo, ... */ + ELF_T_MOVE, /* Elf32_Move, Elf64_Move, ... */ + ELF_T_LIB, /* Elf32_Lib, Elf64_Lib, ... */ + ELF_T_GNUHASH, /* GNU-style hash section. */ + ELF_T_AUXV, /* Elf32_auxv_t, Elf64_auxv_t, ... */ + /* Keep this the last entry. */ + ELF_T_NUM +} Elf_Type; + +/* Descriptor for data to be converted to or from memory format. */ +typedef struct +{ + void *d_buf; /* Pointer to the actual data. */ + Elf_Type d_type; /* Type of this piece of data. */ + unsigned int d_version; /* ELF version. */ + size_t d_size; /* Size in bytes. */ + loff_t d_off; /* Offset into section. */ + size_t d_align; /* Alignment in section. */ +} Elf_Data; + + +/* Commands for `...'. */ +typedef enum +{ + ELF_C_NULL, /* Nothing, terminate, or compute only. */ + ELF_C_READ, /* Read .. */ + ELF_C_RDWR, /* Read and write .. */ + ELF_C_WRITE, /* Write .. */ + ELF_C_CLR, /* Clear flag. */ + ELF_C_SET, /* Set flag. */ + ELF_C_FDDONE, /* Signal that file descriptor will not be + used anymore. */ + ELF_C_FDREAD, /* Read rest of data so that file descriptor + is not used anymore. */ + /* The following are extensions. */ + ELF_C_READ_MMAP, /* Read, but mmap the file if possible. */ + ELF_C_RDWR_MMAP, /* Read and write, with mmap. */ + ELF_C_WRITE_MMAP, /* Write, with mmap. */ + ELF_C_READ_MMAP_PRIVATE, /* Read, but memory is writable, results are + not written to the file. */ + ELF_C_EMPTY, /* Copy basic file data but not the content. */ + /* Keep this the last entry. */ + ELF_C_NUM +} Elf_Cmd; + + +/* Flags for the ELF structures. */ +enum +{ + ELF_F_DIRTY = 0x1, +#define ELF_F_DIRTY ELF_F_DIRTY + ELF_F_LAYOUT = 0x4, +#define ELF_F_LAYOUT ELF_F_LAYOUT + ELF_F_PERMISSIVE = 0x8 +#define ELF_F_PERMISSIVE ELF_F_PERMISSIVE +}; + + +/* Identification values for recognized object files. */ +typedef enum +{ + ELF_K_NONE, /* Unknown. */ + ELF_K_AR, /* Archive. */ + ELF_K_COFF, /* Stupid old COFF. */ + ELF_K_ELF, /* ELF file. */ + /* Keep this the last entry. */ + ELF_K_NUM +} Elf_Kind; + + +/* Archive member header. */ +typedef struct +{ + char *ar_name; /* Name of archive member. */ + time_t ar_date; /* File date. */ + uid_t ar_uid; /* User ID. */ + gid_t ar_gid; /* Group ID. */ + mode_t ar_mode; /* File mode. */ + loff_t ar_size; /* File size. */ + char *ar_rawname; /* Original name of archive member. */ +} Elf_Arhdr; + + +/* Archive symbol table entry. */ +typedef struct +{ + char *as_name; /* Symbol name. */ + size_t as_off; /* Offset for this file in the archive. */ + unsigned long int as_hash; /* Hash value of the name. */ +} Elf_Arsym; + + +/* Descriptor for the ELF file. */ +typedef struct Elf Elf; + +/* Descriptor for ELF file section. */ +typedef struct Elf_Scn Elf_Scn; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return descriptor for ELF file to work according to CMD. */ +extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref); + +/* Create a clone of an existing ELF descriptor. */ + extern Elf *elf_clone (Elf *__elf, Elf_Cmd __cmd); + +/* Create descriptor for memory region. */ +extern Elf *elf_memory (char *__image, size_t __size); + +/* Advance archive descriptor to next element. */ +extern Elf_Cmd elf_next (Elf *__elf); + +/* Free resources allocated for ELF. */ +extern int elf_end (Elf *__elf); + +/* Update ELF descriptor and write file to disk. */ +extern loff_t elf_update (Elf *__elf, Elf_Cmd __cmd); + +/* Determine what kind of file is associated with ELF. */ +extern Elf_Kind elf_kind (Elf *__elf) __attribute__ ((__pure__)); + +/* Get the base offset for an object file. */ +extern loff_t elf_getbase (Elf *__elf); + + +/* Retrieve file identification data. */ +extern char *elf_getident (Elf *__elf, size_t *__nbytes); + +/* Retrieve class-dependent object file header. */ +extern Elf32_Ehdr *elf32_getehdr (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Ehdr *elf64_getehdr (Elf *__elf); + +/* Create ELF header if none exists. */ +extern Elf32_Ehdr *elf32_newehdr (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Ehdr *elf64_newehdr (Elf *__elf); + +/* Get the number of program headers in the ELF file. If the file uses + more headers than can be represented in the e_phnum field of the ELF + header the information from the sh_info field in the zeroth section + header is used. */ +extern int elf_getphdrnum (Elf *__elf, size_t *__dst); + +/* Retrieve class-dependent program header table. */ +extern Elf32_Phdr *elf32_getphdr (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Phdr *elf64_getphdr (Elf *__elf); + +/* Create ELF program header. */ +extern Elf32_Phdr *elf32_newphdr (Elf *__elf, size_t __cnt); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Phdr *elf64_newphdr (Elf *__elf, size_t __cnt); + + +/* Get section at INDEX. */ +extern Elf_Scn *elf_getscn (Elf *__elf, size_t __index); + +/* Get section at OFFSET. */ +extern Elf_Scn *elf32_offscn (Elf *__elf, Elf32_Off __offset); +/* Similar bug this time the binary calls is ELFCLASS64. */ +extern Elf_Scn *elf64_offscn (Elf *__elf, Elf64_Off __offset); + +/* Get index of section. */ +extern size_t elf_ndxscn (Elf_Scn *__scn); + +/* Get section with next section index. */ +extern Elf_Scn *elf_nextscn (Elf *__elf, Elf_Scn *__scn); + +/* Create a new section and append it at the end of the table. */ +extern Elf_Scn *elf_newscn (Elf *__elf); + +/* Get the section index of the extended section index table for the + given symbol table. */ +extern int elf_scnshndx (Elf_Scn *__scn); + +/* Get the number of sections in the ELF file. If the file uses more + sections than can be represented in the e_shnum field of the ELF + header the information from the sh_size field in the zeroth section + header is used. */ +extern int elf_getshdrnum (Elf *__elf, size_t *__dst); +/* Sun messed up the implementation of 'elf_getshnum' in their implementation. + It was agreed to make the same functionality available under a different + name and obsolete the old name. */ +extern int elf_getshnum (Elf *__elf, size_t *__dst) + __attribute__ ((__deprecated__)); + + +/* Get the section index of the section header string table in the ELF + file. If the index cannot be represented in the e_shnum field of + the ELF header the information from the sh_link field in the zeroth + section header is used. */ +extern int elf_getshdrstrndx (Elf *__elf, size_t *__dst); +/* Sun messed up the implementation of 'elf_getshnum' in their implementation. + It was agreed to make the same functionality available under a different + name and obsolete the old name. */ +extern int elf_getshstrndx (Elf *__elf, size_t *__dst) + __attribute__ ((__deprecated__)); + + +/* Retrieve section header of ELFCLASS32 binary. */ +extern Elf32_Shdr *elf32_getshdr (Elf_Scn *__scn); +/* Similar for ELFCLASS64. */ +extern Elf64_Shdr *elf64_getshdr (Elf_Scn *__scn); + + +/* Set or clear flags for ELF file. */ +extern unsigned int elf_flagelf (Elf *__elf, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the ELF header. */ +extern unsigned int elf_flagehdr (Elf *__elf, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the ELF program header. */ +extern unsigned int elf_flagphdr (Elf *__elf, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the given ELF section. */ +extern unsigned int elf_flagscn (Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the given ELF data. */ +extern unsigned int elf_flagdata (Elf_Data *__data, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the given ELF section header. */ +extern unsigned int elf_flagshdr (Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned int __flags); + + +/* Get data from section while translating from file representation + to memory representation. */ +extern Elf_Data *elf_getdata (Elf_Scn *__scn, Elf_Data *__data); + +/* Get uninterpreted section content. */ +extern Elf_Data *elf_rawdata (Elf_Scn *__scn, Elf_Data *__data); + +/* Create new data descriptor for section SCN. */ +extern Elf_Data *elf_newdata (Elf_Scn *__scn); + +/* Get data translated from a chunk of the file contents as section data + would be for TYPE. The resulting Elf_Data pointer is valid until + elf_end (ELF) is called. */ +extern Elf_Data *elf_getdata_rawchunk (Elf *__elf, + loff_t __offset, size_t __size, + Elf_Type __type); + + +/* Return pointer to string at OFFSET in section INDEX. */ +extern char *elf_strptr (Elf *__elf, size_t __index, size_t __offset); + + +/* Return header of archive. */ +extern Elf_Arhdr *elf_getarhdr (Elf *__elf); + +/* Return offset in archive for current file ELF. */ +extern loff_t elf_getaroff (Elf *__elf); + +/* Select archive element at OFFSET. */ +extern size_t elf_rand (Elf *__elf, size_t __offset); + +/* Get symbol table of archive. */ +extern Elf_Arsym *elf_getarsym (Elf *__elf, size_t *__narsyms); + + +/* Control ELF descriptor. */ +extern int elf_cntl (Elf *__elf, Elf_Cmd __cmd); + +/* Retrieve uninterpreted file contents. */ +extern char *elf_rawfile (Elf *__elf, size_t *__nbytes); + + +/* Return size of array of COUNT elements of the type denoted by TYPE + in the external representation. The binary class is taken from ELF. + The result is based on version VERSION of the ELF standard. */ +extern size_t elf32_fsize (Elf_Type __type, size_t __count, + unsigned int __version) + __attribute__ ((__const__)); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern size_t elf64_fsize (Elf_Type __type, size_t __count, + unsigned int __version) + __attribute__ ((__const__)); + + +/* Convert data structure from the representation in the file represented + by ELF to their memory representation. */ +extern Elf_Data *elf32_xlatetom (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); +/* Same for 64 bit class. */ +extern Elf_Data *elf64_xlatetom (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); + +/* Convert data structure from to the representation in memory + represented by ELF file representation. */ +extern Elf_Data *elf32_xlatetof (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); +/* Same for 64 bit class. */ +extern Elf_Data *elf64_xlatetof (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); + + +/* Return error code of last failing function call. This value is kept + separately for each thread. */ +extern int elf_errno (void); + +/* Return error string for ERROR. If ERROR is zero, return error string + for most recent error or NULL is none occurred. If ERROR is -1 the + behaviour is similar to the last case except that not NULL but a legal + string is returned. */ +extern const char *elf_errmsg (int __error); + + +/* Coordinate ELF library and application versions. */ +extern unsigned int elf_version (unsigned int __version); + +/* Set fill bytes used to fill holes in data structures. */ +extern void elf_fill (int __fill); + +/* Compute hash value. */ +extern unsigned long int elf_hash (const char *__string) + __attribute__ ((__pure__)); + +/* Compute hash value using the GNU-specific hash function. */ +extern unsigned long int elf_gnu_hash (const char *__string) + __attribute__ ((__pure__)); + + +/* Compute simple checksum from permanent parts of the ELF file. */ +extern long int elf32_checksum (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern long int elf64_checksum (Elf *__elf); + +#ifdef __cplusplus +} +#endif + +#endif /* libelf.h */ diff --git a/libelf/libelf.map b/libelf/libelf.map new file mode 100644 index 0000000..de6d912 --- /dev/null +++ b/libelf/libelf.map @@ -0,0 +1,140 @@ +ELFUTILS_1.0 { + global: + elf32_checksum; + elf32_fsize; + elf32_getehdr; + elf32_getphdr; + elf32_getshdr; + elf32_newehdr; + elf32_newphdr; + elf32_xlatetof; + elf32_xlatetom; + elf64_checksum; + elf64_fsize; + elf64_getehdr; + elf64_getphdr; + elf64_getshdr; + elf64_newehdr; + elf64_newphdr; + elf64_xlatetof; + elf64_xlatetom; + elf_begin; + elf_clone; + elf_cntl; + elf_end; + elf_errmsg; + elf_errno; + elf_fill; + elf_flagdata; + elf_flagehdr; + elf_flagelf; + elf_flagphdr; + elf_flagscn; + elf_flagshdr; + elf_getarhdr; + elf_getarsym; + elf_getbase; + elf_getdata; + elf_getident; + elf_getscn; + elf_getshnum; + elf_getshstrndx; + elf_hash; + elf_kind; + elf_memory; + elf_ndxscn; + elf_newdata; + elf_newscn; + elf_next; + elf_nextscn; + elf_rand; + elf_rawdata; + elf_rawfile; + elf_scncnt; + elf_strptr; + elf_update; + elf_version; + gelf_checksum; + gelf_fsize; + gelf_getclass; + gelf_getdyn; + gelf_getehdr; + gelf_getmove; + gelf_getphdr; + gelf_getrel; + gelf_getrela; + gelf_getshdr; + gelf_getsym; + gelf_getsyminfo; + gelf_getsymshndx; + gelf_getverdaux; + gelf_getverdef; + gelf_getvernaux; + gelf_getverneed; + gelf_getversym; + gelf_newehdr; + gelf_newphdr; + gelf_update_dyn; + gelf_update_ehdr; + gelf_update_move; + gelf_update_phdr; + gelf_update_rel; + gelf_update_rela; + gelf_update_shdr; + gelf_update_sym; + gelf_update_syminfo; + gelf_update_symshndx; + gelf_update_verdaux; + gelf_update_verdef; + gelf_update_vernaux; + gelf_update_verneed; + gelf_update_versym; + gelf_xlatetof; + gelf_xlatetom; + nlist; + + local: + *; +}; + +ELFUTILS_1.1 { + global: + gelf_getlib; + gelf_update_lib; +} ELFUTILS_1.0; + +ELFUTILS_1.1.1 { + global: + elf32_offscn; + elf64_offscn; + gelf_offscn; + elf_getaroff; +} ELFUTILS_1.1; + +ELFUTILS_1.2 { + global: + elf_gnu_hash; +} ELFUTILS_1.1.1; + +ELFUTILS_1.3 { + global: + elf_getdata_rawchunk; + gelf_getauxv; + gelf_update_auxv; + gelf_getnote; +} ELFUTILS_1.2; + +ELFUTILS_1.4 { + global: + elf_scnshndx; +} ELFUTILS_1.3; + +ELFUTILS_1.5 { + global: + elf_getshdrnum; elf_getshdrstrndx; +} ELFUTILS_1.4; + +ELFUTILS_1.6 { + global: + elf_getphdrnum; +} ELFUTILS_1.5; diff --git a/libelf/libelfP.h b/libelf/libelfP.h new file mode 100644 index 0000000..2b8391b --- /dev/null +++ b/libelf/libelfP.h @@ -0,0 +1,611 @@ +/* Internal interfaces for libelf. + Copyright (C) 1998-2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _LIBELFP_H +#define _LIBELFP_H 1 + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <ar.h> +#include <gelf.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +/* gettext helper macros. */ +#define _(Str) dgettext ("elfutils", Str) + + +/* Helper Macros to write 32 bit and 64 bit functions. */ +#define __elfw2_(Bits, Name) __elf##Bits##_##Name +#define elfw2_(Bits, Name) elf##Bits##_##Name +#define ElfW2_(Bits, Name) Elf##Bits##_##Name +#define ELFW2_(Bits, Name) ELF##Bits##_##Name +#define ELFW_(Name, Bits) Name##Bits +#define __elfw2(Bits, Name) __elfw2_(Bits, Name) +#define elfw2(Bits, Name) elfw2_(Bits, Name) +#define ElfW2(Bits, Name) ElfW2_(Bits, Name) +#define ELFW2(Bits, Name) ELFW2_(Bits, Name) +#define ELFW(Name, Bits) ELFW_(Name, Bits) + + +/* Sizes of the external types, for 32 bits objects. */ +#define ELF32_FSZ_ADDR 4 +#define ELF32_FSZ_OFF 4 +#define ELF32_FSZ_HALF 2 +#define ELF32_FSZ_WORD 4 +#define ELF32_FSZ_SWORD 4 +#define ELF32_FSZ_XWORD 8 +#define ELF32_FSZ_SXWORD 8 + +/* Same for 64 bits objects. */ +#define ELF64_FSZ_ADDR 8 +#define ELF64_FSZ_OFF 8 +#define ELF64_FSZ_HALF 2 +#define ELF64_FSZ_WORD 4 +#define ELF64_FSZ_SWORD 4 +#define ELF64_FSZ_XWORD 8 +#define ELF64_FSZ_SXWORD 8 + + +/* This is an extension of the ELF_F_* enumeration. The values here are + not part of the library interface, they are only used internally. */ +enum +{ + ELF_F_MMAPPED = 0x40, + ELF_F_MALLOCED = 0x80, + ELF_F_FILEDATA = 0x100 +}; + + +/* Get definition of all the external types. */ +#include "exttypes.h" + + +/* Error values. */ +enum +{ + ELF_E_NOERROR = 0, + ELF_E_UNKNOWN_ERROR, + ELF_E_UNKNOWN_VERSION, + ELF_E_UNKNOWN_TYPE, + ELF_E_INVALID_HANDLE, + ELF_E_SOURCE_SIZE, + ELF_E_DEST_SIZE, + ELF_E_INVALID_ENCODING, + ELF_E_NOMEM, + ELF_E_INVALID_FILE, + ELF_E_INVALID_OP, + ELF_E_NO_VERSION, + ELF_E_INVALID_CMD, + ELF_E_RANGE, + ELF_E_ARCHIVE_FMAG, + ELF_E_INVALID_ARCHIVE, + ELF_E_NO_ARCHIVE, + ELF_E_NO_INDEX, + ELF_E_READ_ERROR, + ELF_E_WRITE_ERROR, + ELF_E_INVALID_CLASS, + ELF_E_INVALID_INDEX, + ELF_E_INVALID_OPERAND, + ELF_E_INVALID_SECTION, + ELF_E_INVALID_COMMAND, + ELF_E_WRONG_ORDER_EHDR, + ELF_E_FD_DISABLED, + ELF_E_FD_MISMATCH, + ELF_E_OFFSET_RANGE, + ELF_E_NOT_NUL_SECTION, + ELF_E_DATA_MISMATCH, + ELF_E_INVALID_SECTION_HEADER, + ELF_E_INVALID_DATA, + ELF_E_DATA_ENCODING, + ELF_E_SECTION_TOO_SMALL, + ELF_E_INVALID_ALIGN, + ELF_E_INVALID_SHENTSIZE, + ELF_E_UPDATE_RO, + ELF_E_NOFILE, + ELF_E_GROUP_NOT_REL, + ELF_E_INVALID_PHDR, + ELF_E_NO_PHDR, + ELF_E_INVALID_OFFSET, + /* Keep this as the last entry. */ + ELF_E_NUM +}; + + +/* The visible `Elf_Data' type is not sufficent for some operations due + to a misdesigned interface. Extend it for internal purposes. */ +typedef struct +{ + Elf_Data d; + Elf_Scn *s; +} Elf_Data_Scn; + + +/* List of `Elf_Data' descriptors. This is what makes up the section + contents. */ +typedef struct Elf_Data_List +{ + /* `data' *must* be the first element in the struct. */ + Elf_Data_Scn data; + struct Elf_Data_List *next; + int flags; +} Elf_Data_List; + + +/* Descriptor for ELF section. */ +struct Elf_Scn +{ + /* We have to distinguish several different situations: + + 1. the section is user created. Therefore there is no file or memory + region to read the data from. Here we have two different subcases: + + a) data was not yet added (before the first `elf_newdata' call) + + b) at least one data set is available + + 2. this is a section from a file/memory region. We have to read the + current content in one data block if we have to. But we don't + read the data until it is necessary. So we have the subcases: + + a) the section in the file has size zero (for whatever reason) + + b) the data of the file is not (yet) read + + c) the data is read and available. + + In addition to this we have different data sets, the raw and the converted + data. This distinction only exists for the data read from the file. + All user-added data set (all but the first when read from the file or + all of them for user-create sections) are the same in both formats. + We don't create the converted data before it is necessary. + + The `data_read' element signals whether data is available in the + raw format. + + If there is data from the file/memory region or if read one data + set is added the `rawdata_list_read' pointer in non-NULL and points + to the last filled data set. `raw_datalist_rear' is therefore NULL + only if there is no data set at all. + + This so far allows to distinguish all but two cases (given that the + `rawdata_list' and `data_list' entries are initialized to zero) is + between not yet loaded data from the file/memory region and a section + with zero size and type ELF_T_BYTE. */ + Elf_Data_List data_list; /* List of data buffers. */ + Elf_Data_List *data_list_rear; /* Pointer to the rear of the data list. */ + + Elf_Data_Scn rawdata; /* Uninterpreted data of the section. */ + + int data_read; /* Nonzero if the section was created by the + user or if the data from the file/memory + is read. */ + int shndx_index; /* Index of the extended section index + table for this symbol table (if this + section is a symbol table). */ + + size_t index; /* Index of this section. */ + struct Elf *elf; /* The underlying ELF file. */ + + union + { + Elf32_Shdr *e32; /* Pointer to 32bit section header. */ + Elf64_Shdr *e64; /* Pointer to 64bit section header. */ + } shdr; + + unsigned int shdr_flags; /* Section header modified? */ + unsigned int flags; /* Section changed in size? */ + + char *rawdata_base; /* The unmodified data of the section. */ + char *data_base; /* The converted data of the section. */ + + struct Elf_ScnList *list; /* Pointer the the section list element the + data is in. */ +}; + + +/* List of section. */ +typedef struct Elf_ScnList +{ + unsigned int cnt; /* Number of elements of 'data' used. */ + unsigned int max; /* Number of elements of 'data' allocated. */ + struct Elf_ScnList *next; /* Next block of sections. */ + struct Elf_Scn data[0]; /* Section data. */ +} Elf_ScnList; + + +/* elf_getdata_rawchunk result. */ +typedef struct Elf_Data_Chunk +{ + Elf_Data_Scn data; + union + { + Elf_Scn dummy_scn; + struct Elf_Data_Chunk *next; + }; +} Elf_Data_Chunk; + + +/* The ELF descriptor. */ +struct Elf +{ + /* Address to which the file was mapped. NULL if not mapped. */ + void *map_address; + + /* When created for an archive member this points to the descriptor + for the archive. */ + Elf *parent; + Elf *next; /* Used in list of archive descriptors. */ + + /* What kind of file is underneath (ELF file, archive...). */ + Elf_Kind kind; + + /* Command used to create this descriptor. */ + Elf_Cmd cmd; + + /* The binary class. */ + unsigned int class; + + /* The used file descriptor. -1 if not available anymore. */ + int fildes; + + /* Offset in the archive this file starts or zero. */ + off_t start_offset; + + /* Size of the file in the archive or the entire file size, or ~0 + for an (yet) unknown size. */ + size_t maximum_size; + + /* Describes the way the memory was allocated and if the dirty bit is + signalled it means that the whole file has to be rewritten since + the layout changed. */ + int flags; + + /* Reference counting for the descriptor. */ + int ref_count; + + /* Lock to handle multithreaded programs. */ + rwlock_define (,lock); + + union + { + struct + { + /* The next fields are only useful when testing for ==/!= NULL. */ + void *ehdr; + void *shdr; + void *phdr; + + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ + Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ + int phdr_flags; /* Flags (dirty|malloc) for program header. */ + int shdr_malloced; /* Nonzero if shdr array was allocated. */ + off64_t sizestr_offset; /* Offset of the size string in the parent + if this is an archive member. */ + } elf; + + struct + { + Elf32_Ehdr *ehdr; /* Pointer to the ELF header. This is + never malloced. */ + Elf32_Shdr *shdr; /* Used when reading from a file. */ + Elf32_Phdr *phdr; /* Pointer to the program header array. */ + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ + Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ + int phdr_flags; /* Flags (dirty|malloc) for program header. */ + int shdr_malloced; /* Nonzero if shdr array was allocated. */ + off64_t sizestr_offset; /* Offset of the size string in the parent + if this is an archive member. */ + Elf32_Ehdr ehdr_mem; /* Memory used for ELF header when not + mmaped. */ + char __e32scnspad[sizeof (Elf64_Ehdr) - sizeof (Elf32_Ehdr)]; + + /* The section array. */ + Elf_ScnList scns; + } elf32; + + struct + { + Elf64_Ehdr *ehdr; /* Pointer to the ELF header. This is + never malloced. */ + Elf64_Shdr *shdr; /* Used when reading from a file. */ + Elf64_Phdr *phdr; /* Pointer to the program header array. */ + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ + Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ + int phdr_flags; /* Flags (dirty|malloc) for program header. */ + int shdr_malloced; /* Nonzero if shdr array was allocated. */ + off64_t sizestr_offset; /* Offset of the size string in the parent + if this is an archive member. */ + Elf64_Ehdr ehdr_mem; /* Memory used for ELF header when not + mmaped. */ + + /* The section array. */ + Elf_ScnList scns; + } elf64; + + struct + { + Elf *children; /* List of all descriptors for this archive. */ + Elf_Arsym *ar_sym; /* Symbol table returned by elf_getarsym. */ + size_t ar_sym_num; /* Number of entries in `ar_sym'. */ + char *long_names; /* If no index is available but long names + are used this elements points to the data.*/ + size_t long_names_len; /* Length of the long name table. */ + off_t offset; /* Offset in file we are currently at. + elf_next() advances this to the next + member of the archive. */ + Elf_Arhdr elf_ar_hdr; /* Structure returned by 'elf_getarhdr'. */ + struct ar_hdr ar_hdr; /* Header read from file. */ + char ar_name[16]; /* NUL terminated ar_name of elf_ar_hdr. */ + char raw_name[17]; /* This is a buffer for the NUL terminated + named raw_name used in the elf_ar_hdr. */ + } ar; + } state; + + /* There absolutely never must be anything following the union. */ +}; + +/* Type of the conversion functions. These functions will convert the + byte order. */ +typedef void (*xfct_t) (void *, const void *, size_t, int); + +/* The table with the function pointers. */ +extern const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden; +extern const xfct_t __elf_xfctstof[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden; + + +/* Array with sizes of the external types indexed by ELF version, binary + class, and type. */ +extern const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden; +/* We often have to access the size for a type in the current version. */ +#if EV_NUM != 2 +# define elf_typesize(class,type,n) \ + elfw2(class,fsize) (type, n, __libelf_version) +#else +# define elf_typesize(class,type,n) \ + (__libelf_type_sizes[EV_CURRENT - 1][ELFW(ELFCLASS,class) - 1][type] * n) +#endif + +/* Currently selected version of the ELF specification. */ +extern unsigned int __libelf_version attribute_hidden; + +/* The byte value used for filling gaps. */ +extern int __libelf_fill_byte attribute_hidden; + +/* Nonzero if the version was set. */ +extern int __libelf_version_initialized attribute_hidden; + +/* Index for __libelf_type_sizes et al. */ +#if EV_NUM == 2 +# define LIBELF_EV_IDX 0 +#else +# define LIBELF_EV_IDX (__libelf_version - 1) +#endif + +#if !ALLOW_UNALIGNED +/* Array with alignment requirements of the internal types indexed by ELF + version, binary class, and type. */ +extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden; +# define __libelf_type_align(class, type) \ + (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1) +#else +# define __libelf_type_align(class, type) 1 +#endif + +/* The libelf API does not have such a function but it is still useful. + Get the memory size for the given type. + + These functions cannot be marked internal since they are aliases + of the export elfXX_fsize functions.*/ +extern size_t __elf32_msize (Elf_Type __type, size_t __count, + unsigned int __version); +extern size_t __elf64_msize (Elf_Type __type, size_t __count, + unsigned int __version); + + +/* Create Elf descriptor from memory image. */ +extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address, + off_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent) + internal_function; + +/* Set error value. */ +extern void __libelf_seterrno (int value) internal_function; + +/* Get the next archive header. */ +extern int __libelf_next_arhdr_wrlock (Elf *elf) internal_function; + +/* Read all of the file associated with the descriptor. */ +extern char *__libelf_readall (Elf *elf) internal_function; + +/* Read the complete section table and convert the byte order if necessary. */ +extern int __libelf_readsections (Elf *elf) internal_function; + +/* Store the information for the raw data in the `rawdata_list' element. */ +extern int __libelf_set_rawdata (Elf_Scn *scn) internal_function; +extern int __libelf_set_rawdata_wrlock (Elf_Scn *scn) internal_function; + + +/* Helper functions for elf_update. */ +extern off_t __elf32_updatenull_wrlock (Elf *elf, int *change_bop, + size_t shnum) internal_function; +extern off_t __elf64_updatenull_wrlock (Elf *elf, int *change_bop, + size_t shnum) internal_function; + +extern int __elf32_updatemmap (Elf *elf, int change_bo, size_t shnum) + internal_function; +extern int __elf64_updatemmap (Elf *elf, int change_bo, size_t shnum) + internal_function; +extern int __elf32_updatefile (Elf *elf, int change_bo, size_t shnum) + internal_function; +extern int __elf64_updatefile (Elf *elf, int change_bo, size_t shnum) + internal_function; + + +/* Alias for exported functions to avoid PLT entries, and + rdlock/wrlock variants of these functions. */ +extern int __elf_end_internal (Elf *__elf) attribute_hidden; +extern Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref) + attribute_hidden; +extern Elf32_Ehdr *__elf32_getehdr_wrlock (Elf *__elf) internal_function; +extern Elf64_Ehdr *__elf64_getehdr_wrlock (Elf *__elf) internal_function; +extern Elf32_Ehdr *__elf32_newehdr_internal (Elf *__elf) attribute_hidden; +extern Elf64_Ehdr *__elf64_newehdr_internal (Elf *__elf) attribute_hidden; +extern Elf32_Phdr *__elf32_getphdr_internal (Elf *__elf) attribute_hidden; +extern Elf64_Phdr *__elf64_getphdr_internal (Elf *__elf) attribute_hidden; +extern Elf32_Phdr *__elf32_getphdr_wrlock (Elf *__elf) attribute_hidden; +extern Elf64_Phdr *__elf64_getphdr_wrlock (Elf *__elf) attribute_hidden; +extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt) + attribute_hidden; +extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt) + attribute_hidden; +extern Elf_Scn *__elf32_offscn_internal (Elf *__elf, Elf32_Off __offset) + attribute_hidden; +extern Elf_Scn *__elf64_offscn_internal (Elf *__elf, Elf64_Off __offset) + attribute_hidden; +extern int __elf_getphdrnum_rdlock (Elf *__elf, size_t *__dst) + internal_function; +extern int __elf_getshdrnum_rdlock (Elf *__elf, size_t *__dst) + internal_function; +extern int __elf_getshdrstrndx_internal (Elf *__elf, size_t *__dst) + attribute_hidden; +extern Elf32_Shdr *__elf32_getshdr_rdlock (Elf_Scn *__scn) internal_function; +extern Elf64_Shdr *__elf64_getshdr_rdlock (Elf_Scn *__scn) internal_function; +extern Elf32_Shdr *__elf32_getshdr_wrlock (Elf_Scn *__scn) internal_function; +extern Elf64_Shdr *__elf64_getshdr_wrlock (Elf_Scn *__scn) internal_function; +extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index) + attribute_hidden; +extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn) + attribute_hidden; +extern int __elf_scnshndx_internal (Elf_Scn *__scn) attribute_hidden; +extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data) + attribute_hidden; +extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data) + internal_function; +extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data) + attribute_hidden; +extern char *__elf_strptr_internal (Elf *__elf, size_t __index, + size_t __offset) attribute_hidden; +extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern Elf_Data *__elf64_xlatetom_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern Elf_Data *__elf32_xlatetof_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern Elf_Data *__elf64_xlatetof_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern unsigned int __elf_version_internal (unsigned int __version) + attribute_hidden; +extern unsigned long int __elf_hash_internal (const char *__string) + __attribute__ ((__pure__, visibility ("hidden"))); +extern long int __elf32_checksum_internal (Elf *__elf) attribute_hidden; +extern long int __elf64_checksum_internal (Elf *__elf) attribute_hidden; + + +extern GElf_Ehdr *__gelf_getehdr_rdlock (Elf *__elf, GElf_Ehdr *__dest) + internal_function; +extern size_t __gelf_fsize_internal (Elf *__elf, Elf_Type __type, + size_t __count, unsigned int __version) + attribute_hidden; +extern GElf_Shdr *__gelf_getshdr_internal (Elf_Scn *__scn, GElf_Shdr *__dst) + attribute_hidden; +extern GElf_Sym *__gelf_getsym_internal (Elf_Data *__data, int __ndx, + GElf_Sym *__dst) attribute_hidden; + + +extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len) + attribute_hidden; + + +/* We often have to update a flag iff a value changed. Make this + convenient. */ +#define update_if_changed(var, exp, flag) \ + do { \ + __typeof__ (var) *_var = &(var); \ + __typeof__ (exp) _exp = (exp); \ + if (*_var != _exp) \ + { \ + *_var = _exp; \ + (flag) |= ELF_F_DIRTY; \ + } \ + } while (0) + +/* Align offset to 4 bytes as needed for note name and descriptor data. */ +#define NOTE_ALIGN(n) (((n) + 3) & -4U) + +#endif /* libelfP.h */ diff --git a/libelf/libelf_crc32.c b/libelf/libelf_crc32.c new file mode 100644 index 0000000..10ce34c --- /dev/null +++ b/libelf/libelf_crc32.c @@ -0,0 +1,56 @@ +/* Copyright (C) 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#define crc32 attribute_hidden __libelf_crc32 +#define LIB_SYSTEM_H 1 +#include <libelf.h> +#include "../lib/crc32.c" diff --git a/libelf/libelf_next_prime.c b/libelf/libelf_next_prime.c new file mode 100644 index 0000000..1b96012 --- /dev/null +++ b/libelf/libelf_next_prime.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#define next_prime attribute_hidden __libelf_next_prime +#include "../lib/next_prime.c" diff --git a/libelf/nlist.c b/libelf/nlist.c new file mode 100644 index 0000000..f1fe176 --- /dev/null +++ b/libelf/nlist.c @@ -0,0 +1,264 @@ +/* Extract symbol list from binary. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <fcntl.h> +#include <gelf.h> +#include <libelf.h> +#include <nlist.h> +#include <unistd.h> + +#include "libelfP.h" + + +struct hashentry +{ + const char *str; + GElf_Sym sym; +}; +#define TYPE struct hashentry +/* XXX Use a better hash function some day. */ +#define HASHFCT(str, len) INTUSE(elf_hash) (str) +#define COMPARE(p1, p2) strcmp ((p1)->str, (p2)->str) +#define CLASS static +#define PREFIX nlist_ +#define xcalloc(n, m) calloc (n, m) +#define next_prime(s) __libelf_next_prime (s) +#include <fixedsizehash.h> + + +int +nlist (const char *filename, struct nlist *nl) +{ + int fd; + Elf *elf; + Elf_Scn *scn = NULL; + Elf_Scn *symscn = NULL; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = NULL; + Elf_Data *data; + struct nlist_fshash *table; + size_t nsyms; + size_t cnt; + + /* Open the file. */ + fd = open (filename, O_RDONLY); + if (fd == -1) + { + __libelf_seterrno (ELF_E_NOFILE); + goto fail; + } + + /* For compatibility reasons (`nlist' existed before ELF and libelf) + we don't expect the caller to set the ELF version. Do this here + if it hasn't happened yet. */ + if (__libelf_version_initialized == 0) + INTUSE(elf_version) (EV_CURRENT); + + /* Now get an ELF descriptor. */ + elf = INTUSE(elf_begin) (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + goto fail_fd; + + /* Find a symbol table. We prefer the real symbol table but if it + does not exist use the dynamic symbol table. */ + while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL) + { + shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem); + if (shdr == NULL) + goto fail_close; + + /* That is what we are looking for. */ + if (shdr->sh_type == SHT_SYMTAB) + { + symscn = scn; + break; + } + + /* Better than nothing. Remember this section. */ + if (shdr->sh_type == SHT_DYNSYM) + symscn = scn; + } + + if (symscn == NULL) + /* We haven't found anything. Fail. */ + goto fail_close; + + /* Re-get the section header in case we found only the dynamic symbol + table. */ + if (scn == NULL) + shdr = INTUSE(gelf_getshdr) (symscn, &shdr_mem); + /* SHDR->SH_LINK now contains the index of the string section. */ + + /* Get the data for the symbol section. */ + data = INTUSE(elf_getdata) (symscn, NULL); + if (data == NULL) + goto fail_close; + + /* How many symbols are there? */ + nsyms = (shdr->sh_size + / INTUSE(gelf_fsize) (elf, ELF_T_SYM, 1, data->d_version)); + + /* Create the hash table. */ + table = nlist_fshash_init (nsyms); + if (table == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto fail_close; + } + + /* Iterate over all the symbols in the section. */ + for (cnt = 0; cnt < nsyms; ++cnt) + { + struct hashentry mem; + GElf_Sym *sym; + + /* Get the symbol. */ + sym = INTUSE(gelf_getsym) (data, cnt, &mem.sym); + if (sym == NULL) + goto fail_dealloc; + + /* Get the name of the symbol. */ + mem.str = INTUSE(elf_strptr) (elf, shdr->sh_link, sym->st_name); + if (mem.str == NULL) + goto fail_dealloc; + + /* Don't allow zero-length strings. */ + if (mem.str[0] == '\0') + continue; + + /* And add it to the hash table. Note that we are using the + overwrite version. This will ensure that + a) global symbols are preferred over local symbols since + they are all located at the end + b) if there are multiple local symbols with the same name + the last one is used. + */ + (void) nlist_fshash_overwrite (table, mem.str, 0, &mem); + } + + /* Now it is time to look for the symbols the user asked for. + XXX What is a `null name/null string'? This is what the + standard says terminates the list. Is it a null pointer + or a zero-length string? We test for both... */ + while (nl->n_name != NULL && nl->n_name[0] != '\0') + { + struct hashentry search; + const struct hashentry *found; + + /* Search for a matching entry in the hash table. */ + search.str = nl->n_name; + found = nlist_fshash_find (table, nl->n_name, 0, &search); + + if (found != NULL) + { + /* Found it. */ + nl->n_value = found->sym.st_value; + nl->n_scnum = found->sym.st_shndx; + nl->n_type = GELF_ST_TYPE (found->sym.st_info); + /* XXX What shall we fill in the next fields? */ + nl->n_sclass = 0; + nl->n_numaux = 0; + } + else + { + /* Not there. */ + nl->n_value = 0; + nl->n_scnum = 0; + nl->n_type = 0; + nl->n_sclass = 0; + nl->n_numaux = 0; + } + + /* Next search request. */ + ++nl; + } + + /* Free the resources. */ + nlist_fshash_fini (table); + + /* We do not need the ELF descriptor anymore. */ + (void) INTUSE(elf_end) (elf); + + /* Neither the file descriptor. */ + (void) close (fd); + + return 0; + + fail_dealloc: + nlist_fshash_fini (table); + + fail_close: + /* We do not need the ELF descriptor anymore. */ + (void) INTUSE(elf_end) (elf); + + fail_fd: + /* Neither the file descriptor. */ + (void) close (fd); + + fail: + /* We have to set all entries to zero. */ + while (nl->n_name != NULL && nl->n_name[0] != '\0') + { + nl->n_value = 0; + nl->n_scnum = 0; + nl->n_type = 0; + nl->n_sclass = 0; + nl->n_numaux = 0; + + /* Next entry. */ + ++nl; + } + + return -1; +} diff --git a/libelf/nlist.h b/libelf/nlist.h new file mode 100644 index 0000000..ce6569e --- /dev/null +++ b/libelf/nlist.h @@ -0,0 +1,77 @@ +/* Interface for nlist. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#ifndef _NLIST_H +#define _NLIST_H 1 + + +/* Symbol list type. */ +struct nlist +{ + char *n_name; /* Symbol name. */ + long int n_value; /* Value of symbol. */ + short int n_scnum; /* Section number found in. */ + unsigned short int n_type; /* Type of symbol. */ + char n_sclass; /* Storage class. */ + char n_numaux; /* Number of auxiliary entries. */ +}; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Get specified entries from file. */ +extern int nlist (__const char *__filename, struct nlist *__nl); + +#ifdef __cplusplus +} +#endif + +#endif /* nlist.h */ diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h new file mode 100644 index 0000000..a72fe86 --- /dev/null +++ b/libelf/note_xlate.h @@ -0,0 +1,80 @@ +/* Conversion functions for notes. + Copyright (C) 2007, 2009 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +static void +elf_cvt_note (void *dest, const void *src, size_t len, int encode) +{ + assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); + + while (len >= sizeof (Elf32_Nhdr)) + { + (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr), + encode); + const Elf32_Nhdr *n = encode ? src : dest; + Elf32_Word namesz = NOTE_ALIGN (n->n_namesz); + Elf32_Word descsz = NOTE_ALIGN (n->n_descsz); + + len -= sizeof *n; + src += sizeof *n; + dest += sizeof *n; + + if (namesz > len) + break; + len -= namesz; + if (descsz > len) + break; + len -= descsz; + + if (src != dest) + memcpy (dest, src, namesz + descsz); + + src += namesz + descsz; + dest += namesz + descsz; + } +} diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h new file mode 100644 index 0000000..b32cacd --- /dev/null +++ b/libelf/version_xlate.h @@ -0,0 +1,241 @@ +/* Conversion functions for versioning information. + Copyright (C) 1998, 1999, 2000, 2002, 2003 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 1998. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + <http://www.openinventionnetwork.com>. */ + +#include <assert.h> +#include <gelf.h> + +#include "libelfP.h" + + +static void +elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode) +{ + /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux. + To recognize them we have to walk the data structure and convert + them one after the other. The ENCODE parameter specifies whether + we are encoding or decoding. When we are encoding we can immediately + use the data in the buffer; if not, we have to decode the data before + using it. */ + size_t def_offset = 0; + GElf_Verdef *ddest; + GElf_Verdef *dsrc; + + /* We rely on the types being all the same size. */ + assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux)); + assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux)); + + if (len == 0) + return; + + do + { + size_t aux_offset; + GElf_Verdaux *asrc; + + /* Test for correct offset. */ + if (def_offset + sizeof (GElf_Verdef) > len) + return; + + /* Work the tree from the first record. */ + ddest = (GElf_Verdef *) ((char *) dest + def_offset); + dsrc = (GElf_Verdef *) ((char *) src + def_offset); + + /* Decode first if necessary. */ + if (! encode) + { + ddest->vd_version = bswap_16 (dsrc->vd_version); + ddest->vd_flags = bswap_16 (dsrc->vd_flags); + ddest->vd_ndx = bswap_16 (dsrc->vd_ndx); + ddest->vd_cnt = bswap_16 (dsrc->vd_cnt); + ddest->vd_hash = bswap_32 (dsrc->vd_hash); + ddest->vd_aux = bswap_32 (dsrc->vd_aux); + ddest->vd_next = bswap_32 (dsrc->vd_next); + + aux_offset = def_offset + ddest->vd_aux; + } + else + aux_offset = def_offset + dsrc->vd_aux; + + /* Handle all the auxiliary records belonging to this definition. */ + do + { + GElf_Verdaux *adest; + + /* Test for correct offset. */ + if (aux_offset + sizeof (GElf_Verdaux) > len) + return; + + adest = (GElf_Verdaux *) ((char *) dest + aux_offset); + asrc = (GElf_Verdaux *) ((char *) src + aux_offset); + + if (encode) + aux_offset += asrc->vda_next; + + adest->vda_name = bswap_32 (asrc->vda_name); + adest->vda_next = bswap_32 (asrc->vda_next); + + if (! encode) + aux_offset += adest->vda_next; + } + while (asrc->vda_next != 0); + + /* Encode now if necessary. */ + if (encode) + { + def_offset += dsrc->vd_next; + + ddest->vd_version = bswap_16 (dsrc->vd_version); + ddest->vd_flags = bswap_16 (dsrc->vd_flags); + ddest->vd_ndx = bswap_16 (dsrc->vd_ndx); + ddest->vd_cnt = bswap_16 (dsrc->vd_cnt); + ddest->vd_hash = bswap_32 (dsrc->vd_hash); + ddest->vd_aux = bswap_32 (dsrc->vd_aux); + ddest->vd_next = bswap_32 (dsrc->vd_next); + } + else + def_offset += ddest->vd_next; + } + while (dsrc->vd_next != 0); +} + + +static void +elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode) +{ + /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux. + To recognize them we have to walk the data structure and convert + them one after the other. The ENCODE parameter specifies whether + we are encoding or decoding. When we are encoding we can immediately + use the data in the buffer; if not, we have to decode the data before + using it. */ + size_t need_offset = 0; + GElf_Verneed *ndest; + GElf_Verneed *nsrc; + + /* We rely on the types being all the same size. */ + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux)); + + if (len == 0) + return; + + do + { + size_t aux_offset; + GElf_Vernaux *asrc; + + /* Test for correct offset. */ + if (need_offset + sizeof (GElf_Verneed) > len) + return; + + /* Work the tree from the first record. */ + ndest = (GElf_Verneed *) ((char *) dest + need_offset); + nsrc = (GElf_Verneed *) ((char *) src + need_offset); + + /* Decode first if necessary. */ + if (! encode) + { + ndest->vn_version = bswap_16 (nsrc->vn_version); + ndest->vn_cnt = bswap_16 (nsrc->vn_cnt); + ndest->vn_file = bswap_32 (nsrc->vn_file); + ndest->vn_aux = bswap_32 (nsrc->vn_aux); + ndest->vn_next = bswap_32 (nsrc->vn_next); + + aux_offset = need_offset + ndest->vn_aux; + } + else + aux_offset = need_offset + nsrc->vn_aux; + + /* Handle all the auxiliary records belonging to this requirement. */ + do + { + GElf_Vernaux *adest; + + /* Test for correct offset. */ + if (aux_offset + sizeof (GElf_Vernaux) > len) + return; + + adest = (GElf_Vernaux *) ((char *) dest + aux_offset); + asrc = (GElf_Vernaux *) ((char *) src + aux_offset); + + if (encode) + aux_offset += asrc->vna_next; + + adest->vna_hash = bswap_32 (asrc->vna_hash); + adest->vna_flags = bswap_16 (asrc->vna_flags); + adest->vna_other = bswap_16 (asrc->vna_other); + adest->vna_name = bswap_32 (asrc->vna_name); + adest->vna_next = bswap_32 (asrc->vna_next); + + if (! encode) + aux_offset += adest->vna_next; + } + while (asrc->vna_next != 0); + + /* Encode now if necessary. */ + if (encode) + { + need_offset += nsrc->vn_next; + + ndest->vn_version = bswap_16 (nsrc->vn_version); + ndest->vn_cnt = bswap_16 (nsrc->vn_cnt); + ndest->vn_file = bswap_32 (nsrc->vn_file); + ndest->vn_aux = bswap_32 (nsrc->vn_aux); + ndest->vn_next = bswap_32 (nsrc->vn_next); + } + else + need_offset += ndest->vn_next; + } + while (nsrc->vn_next != 0); +} |