aboutsummaryrefslogtreecommitdiffstats
path: root/src/prelink.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/prelink.h')
-rw-r--r--src/prelink.h632
1 files changed, 632 insertions, 0 deletions
diff --git a/src/prelink.h b/src/prelink.h
new file mode 100644
index 0000000..299f1fa
--- /dev/null
+++ b/src/prelink.h
@@ -0,0 +1,632 @@
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011,
+ 2013 Red Hat, Inc.
+ Copyright (C) 2008 CodeSourcery.
+ Written by Jakub Jelinek <jakub@redhat.com>, 2001.
+ Updated by Maciej W. Rozycki <macro@codesourcery.com>, 2008.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef PRELINK_H
+#define PRELINK_H
+
+#include <elf.h>
+#include <libelf.h>
+#include <gelfx.h>
+#include <ftw.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <utime.h>
+#include <glob.h>
+
+#ifndef HAVE_ELF64_BYTE
+typedef uint8_t Elf64_Byte;
+#endif
+
+#ifndef DT_GNU_LIBLIST
+#define DT_GNU_LIBLIST 0x6ffffef9
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7
+#define DT_GNU_CONFLICT 0x6ffffef8
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6
+#define DT_GNU_PRELINKED 0x6ffffdf5
+#define SHT_GNU_LIBLIST 0x6ffffff7
+#endif
+
+#if DT_GNU_LIBLIST == 0x6ffffef7
+#undef DT_GNU_LIBLIST
+#undef DT_GNU_CONFLICT
+#undef SHT_GNU_LIBLIST
+#define DT_GNU_LIBLIST 0x6ffffef9
+#define DT_GNU_CONFLICT 0x6ffffef8
+#define SHT_GNU_LIBLIST 0x6ffffff7
+#endif
+
+#ifndef DT_GNU_HASH
+#define DT_GNU_HASH 0x6ffffef5
+#define SHT_GNU_HASH 0x6ffffff6
+#endif
+
+#ifndef DT_TLSDESC_PLT
+#define DT_TLSDESC_PLT 0x6ffffef6
+#endif
+
+#ifndef DT_MIPS_RLD_VERSION
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+#endif
+
+#ifndef R_MIPS_TLS_DTPMOD32
+#define R_MIPS_TLS_DTPMOD32 38
+#define R_MIPS_TLS_DTPREL32 39
+#define R_MIPS_TLS_TPREL32 47
+#endif
+
+#ifndef R_MIPS_TLS_DTPMOD64
+#define R_MIPS_TLS_DTPMOD64 40
+#define R_MIPS_TLS_DTPREL64 41
+#define R_MIPS_TLS_TPREL64 48
+#endif
+
+#ifndef R_MIPS_GLOB_DAT
+#define R_MIPS_GLOB_DAT 51
+#endif
+
+#ifndef R_MIPS_COPY
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
+#define STO_MIPS_PLT 0x8
+#define DT_MIPS_PLTGOT 0x70000032
+#define DT_MIPS_RWPLT 0x70000034
+#endif
+
+#ifndef SHT_MIPS_DWARF
+#define SHT_MIPS_DWARF 0x7000001e
+#endif
+
+#ifndef RSS_UNDEF
+#define RSS_UNDEF 0
+#endif
+
+#ifndef R_ARM_TLS_DESC
+#define R_ARM_TLS_DESC 13
+#endif
+
+#ifndef R_ARM_TLS_DTPMOD32
+#define R_ARM_TLS_DTPMOD32 17
+#define R_ARM_TLS_DTPOFF32 18
+#define R_ARM_TLS_TPOFF32 19
+#endif
+
+#ifndef R_386_IRELATIVE
+#define R_386_IRELATIVE 42
+#endif
+
+#ifndef R_X86_64_IRELATIVE
+#define R_X86_64_IRELATIVE 37
+#endif
+
+#ifndef R_PPC_IRELATIVE
+#define R_PPC_IRELATIVE 248
+#endif
+
+#ifndef R_PPC64_JMP_IREL
+#define R_PPC64_JMP_IREL 247
+#define R_PPC64_IRELATIVE 248
+#endif
+
+#ifndef R_390_IRELATIVE
+#define R_390_IRELATIVE 61
+#endif
+
+#ifndef R_ARM_IRELATIVE
+#define R_ARM_IRELATIVE 160
+#endif
+
+struct prelink_entry;
+struct prelink_info;
+struct PLArch;
+struct opd_lib;
+
+struct PLAdjust
+{
+ GElf_Addr start;
+ GElf_Addr adjust;
+};
+
+struct section_move
+{
+ int old_shnum;
+ int new_shnum;
+ int *old_to_new;
+ int *new_to_old;
+};
+
+typedef struct
+{
+ Elf *elf, *elfro;
+ GElf_Ehdr ehdr;
+ GElf_Phdr *phdr;
+ Elf_Scn **scn;
+ GElf_Addr base, end, align;
+ GElf_Addr mask;
+ GElf_Addr info[DT_NUM];
+ GElf_Addr info_DT_GNU_PRELINKED;
+ GElf_Addr info_DT_CHECKSUM;
+ GElf_Addr info_DT_VERNEED, info_DT_VERDEF, info_DT_VERSYM;
+ GElf_Addr info_DT_GNU_HASH;
+ GElf_Addr info_DT_TLSDESC_PLT;
+ GElf_Addr info_DT_MIPS_LOCAL_GOTNO;
+ GElf_Addr info_DT_MIPS_GOTSYM;
+ GElf_Addr info_DT_MIPS_SYMTABNO;
+ GElf_Addr info_DT_MIPS_PLTGOT;
+#define DT_GNU_PRELINKED_BIT 50
+#define DT_CHECKSUM_BIT 51
+#define DT_VERNEED_BIT 52
+#define DT_VERDEF_BIT 53
+#define DT_VERSYM_BIT 54
+#define DT_FILTER_BIT 55
+#define DT_AUXILIARY_BIT 56
+#define DT_LOPROC_BIT 57
+#define DT_GNU_HASH_BIT 58
+#define DT_TLSDESC_PLT_BIT 59
+ uint64_t info_set_mask;
+ int fd, fdro;
+ int lastscn, dynamic;
+ const char *soname;
+ const char *filename, *temp_filename;
+ struct PLArch *arch;
+ struct PLAdjust *adjust;
+ /* .mdebug has absolute file offsets in it. */
+ GElf_Off mdebug_orig_offset;
+ Elf_Data undo;
+ int nadjust;
+ int permissive;
+ struct section_move *move;
+ GElf_Shdr shdr[0];
+} DSO;
+
+static inline int
+dynamic_info_is_set (DSO *dso, int bit)
+{
+ return ((dso)->info_set_mask & (1ULL << (bit))) != 0;
+}
+
+struct layout_libs;
+
+struct PLArch
+{
+ const char *name;
+ int class;
+ int machine;
+ int alternate_machine[3];
+ int max_reloc_size;
+ const char *dynamic_linker;
+ const char *dynamic_linker_alt;
+ int R_COPY;
+ int R_JMP_SLOT;
+ int R_RELATIVE;
+ int rtype_class_valid;
+ int (*arch_adjust) (DSO *dso, GElf_Addr start, GElf_Addr adjust);
+ int (*adjust_section) (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust);
+ int (*adjust_dyn) (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start,
+ GElf_Addr adjust);
+ int (*adjust_rel) (DSO *dso, GElf_Rel *rel, GElf_Addr start,
+ GElf_Addr adjust);
+ int (*adjust_rela) (DSO *dso, GElf_Rela *rela, GElf_Addr start,
+ GElf_Addr adjust);
+ int (*prelink_rel) (struct prelink_info *info, GElf_Rel *rel,
+ GElf_Addr reladdr);
+ int (*prelink_rela) (struct prelink_info *info, GElf_Rela *rela,
+ GElf_Addr relaaddr);
+ int (*prelink_conflict_rel) (DSO *dso, struct prelink_info *info,
+ GElf_Rel *rel, GElf_Addr reladdr);
+ int (*prelink_conflict_rela) (DSO *dso, struct prelink_info *info,
+ GElf_Rela *rela, GElf_Addr relaaddr);
+ int (*arch_prelink_conflict) (DSO *dso, struct prelink_info *info);
+ int (*apply_conflict_rela) (struct prelink_info *info, GElf_Rela *rela,
+ char *buf, GElf_Addr dest_addr);
+ int (*apply_rel) (struct prelink_info *info, GElf_Rel *rel, char *buf);
+ int (*apply_rela) (struct prelink_info *info, GElf_Rela *rela, char *buf);
+ int (*rel_to_rela) (DSO *dso, GElf_Rel *rel, GElf_Rela *rela);
+ int (*rela_to_rel) (DSO *dso, GElf_Rela *rela, GElf_Rel *rel);
+ int (*need_rel_to_rela) (DSO *dso, int first, int last);
+ GElf_Addr (*create_opd) (struct prelink_info *info, int first, int last,
+ int plt);
+ int (*read_opd) (DSO *dso, struct prelink_entry *ent);
+ int (*free_opd) (struct prelink_entry *ent);
+ /* Return reloc size in bytes for given non-COPY reloc type. */
+ int (*reloc_size) (int);
+#define RTYPE_CLASS_VALID 8
+#define RTYPE_CLASS_PLT (8|1)
+#define RTYPE_CLASS_COPY (8|2)
+#define RTYPE_CLASS_TLS (8|4)
+ int (*reloc_class) (int);
+ int (*arch_pre_prelink) (DSO *dso);
+ int (*arch_prelink) (struct prelink_info *info);
+ int (*arch_undo_prelink) (DSO *dso);
+ int (*undo_prelink_rel) (DSO *dso, GElf_Rel *rel, GElf_Addr reladdr);
+ int (*undo_prelink_rela) (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr);
+ int (*layout_libs_init) (struct layout_libs *l);
+ int (*layout_libs_pre) (struct layout_libs *l);
+ int (*layout_libs_post) (struct layout_libs *l);
+ GElf_Addr mmap_base, mmap_end;
+ /* max_page_size is the ELF page size (ELF_MAXPAGESIZE in bfd),
+ page_size is PAGE_SIZE the architecture typically has,
+ or if there are more typical sizes, the smallest one.
+ It doesn't need to be the absolutely smallest supported one,
+ prelink only optimizes for such page_size. */
+ GElf_Addr max_page_size, page_size;
+} __attribute__((aligned(64)));
+
+DSO * open_dso (const char *name);
+DSO * fdopen_dso (int fd, const char *name);
+struct section_move *init_section_move (DSO *dso);
+void add_section (struct section_move *move, int sec);
+void remove_section (struct section_move *move, int sec);
+int reopen_dso (DSO *dso, struct section_move *move, const char *);
+int adjust_symbol_p (DSO *dso, GElf_Sym *sym);
+int check_dso (DSO *dso);
+int dso_is_rdwr (DSO *dso);
+void read_dynamic (DSO *dso);
+int set_dynamic (DSO *dso, GElf_Word tag, GElf_Addr value, int fatal);
+int addr_to_sec (DSO *dso, GElf_Addr addr);
+int adjust_dso (DSO *dso, GElf_Addr start, GElf_Addr adjust);
+int adjust_nonalloc (DSO *dso, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int first,
+ GElf_Addr start, GElf_Addr adjust);
+int adjust_dso_nonalloc (DSO *dso, int first, GElf_Addr start,
+ GElf_Addr adjust);
+int recompute_nonalloc_offsets (DSO *dso);
+int adjust_stabs (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust);
+int adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust);
+int adjust_mdebug (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust);
+int finalize_mdebug (DSO *dso);
+int relocate_dso (DSO *dso, GElf_Addr base);
+int copy_fd_to_file (int fdin, const char *name, struct stat64 *st);
+int update_dso (DSO *dso, const char *);
+int prepare_write_dso (DSO *dso);
+int write_dso (DSO *dso);
+int close_dso (DSO *dso);
+GElf_Addr adjust_old_to_new (DSO *dso, GElf_Addr addr);
+GElf_Addr adjust_new_to_old (DSO *dso, GElf_Addr addr);
+int strtabfind (DSO *dso, int strndx, const char *name);
+int shstrtabadd (DSO *dso, const char *name);
+int dso_has_bad_textrel (DSO *dso);
+
+/* data.c */
+
+/* Used for reading consecutive blocks of data from a DSO. */
+struct data_iterator {
+ /* The DSO that is being read. */
+ DSO *dso;
+
+ /* The data block that contained the last byte to be read.
+ NULL if no data has been read yet or if the end of the
+ DSO has been reached. */
+ Elf_Data *data;
+
+ /* The section that contains DATA, when DATA is nonnull. */
+ int sec;
+
+ /* The address of the next byte. */
+ GElf_Addr addr;
+
+ /* The offset of the next byte from the start of SEC, when DATA
+ is nonnull. */
+ GElf_Addr sec_offset;
+};
+
+unsigned char * get_data (DSO *dso, GElf_Addr addr, int *scnp, Elf_Type *typep);
+#define READWRITEPROTO(le,nn) \
+uint##nn##_t buf_read_u##le##nn (unsigned char *data); \
+uint##nn##_t read_u##le##nn (DSO *dso, GElf_Addr addr); \
+void buf_write_##le##nn (unsigned char *data, uint##nn##_t val);\
+int write_##le##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val);
+#define READWRITEPROTOSIZE(nn) \
+READWRITEPROTO(le,nn) \
+READWRITEPROTO(be,nn) \
+uint##nn##_t buf_read_une##nn (DSO *dso, unsigned char *data); \
+uint##nn##_t read_une##nn (DSO *dso, GElf_Addr addr); \
+void buf_write_ne##nn (DSO *dso, unsigned char *data, \
+ uint##nn##_t val); \
+void write_ne##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val);
+READWRITEPROTO(,8)
+READWRITEPROTOSIZE(16)
+READWRITEPROTOSIZE(32)
+READWRITEPROTOSIZE(64)
+#undef READWRITEPROTO
+#undef READWRITEPROTOSIZE
+const char * strptr (DSO *dso, int sec, off_t offset);
+void init_data_iterator (struct data_iterator *it, DSO *dso, GElf_Addr addr);
+unsigned char *get_data_from_iterator (struct data_iterator *it,
+ GElf_Addr size);
+int get_sym_from_iterator (struct data_iterator *it, GElf_Sym *sym);
+
+#define PL_ARCH(F) \
+static struct PLArch plarch_##F __attribute__((section("pl_arch"),used))
+
+#define addr_adjust(addr, start, adjust) \
+ do { \
+ if (addr >= start) \
+ addr += adjust; \
+ } while (0)
+
+struct prelink_cache_entry
+{
+ uint32_t filename;
+ uint32_t depends;
+ uint32_t checksum;
+#define PCF_UNPRELINKABLE 0x40000
+#define PCF_PRELINKED 0x20000
+#define PCF_ELF64 0x10000
+#define PCF_MACHINE 0x0ffff
+ uint32_t flags;
+ uint32_t ctime;
+ uint32_t mtime;
+ uint64_t base;
+ uint64_t end;
+};
+
+struct prelink_cache
+{
+#define PRELINK_CACHE_NAME "prelink-ELF"
+#define PRELINK_CACHE_VER "0.3.2"
+#define PRELINK_CACHE_MAGIC PRELINK_CACHE_NAME PRELINK_CACHE_VER
+ const char magic [sizeof (PRELINK_CACHE_MAGIC) - 1];
+ uint32_t nlibs;
+ uint32_t ndeps;
+ uint32_t len_strings;
+ uint32_t unused[9];
+ struct prelink_cache_entry entry[0];
+ /* uint32_t depends [ndeps]; */
+ /* const char strings [len_strings]; */
+};
+
+struct prelink_link
+{
+ struct prelink_link *next;
+ const char *canon_filename;
+};
+
+struct prelink_entry
+{
+ const char *filename;
+ const char *canon_filename;
+ const char *soname;
+ struct prelink_link *hardlink;
+ GElf_Word timestamp;
+ GElf_Word checksum;
+ GElf_Addr base, end, layend, pltgot;
+ dev_t dev;
+ ino64_t ino;
+#define ET_BAD (ET_NUM)
+#define ET_CACHE_EXEC (ET_NUM + 1)
+#define ET_CACHE_DYN (ET_NUM + 2)
+#define ET_UNPRELINKABLE (ET_NUM + 3)
+ int type, done, ndepends, refs, flags;
+ union
+ {
+ int explicit;
+ int tmp;
+ } u;
+ uint32_t ctime, mtime;
+ struct prelink_entry **depends;
+ struct prelink_entry *prev, *next;
+ struct opd_lib *opd;
+};
+
+struct prelink_dir
+{
+ dev_t dev;
+ struct prelink_dir *next;
+ size_t len;
+ int flags;
+ char dir[0];
+};
+
+struct prelink_tls
+{
+ GElf_Addr modid;
+ GElf_Addr offset;
+};
+
+struct prelink_symbol
+{
+ union
+ {
+ struct prelink_entry *ent;
+ struct prelink_tls *tls;
+ } u;
+ struct prelink_symbol *next;
+ GElf_Addr value;
+ int reloc_class;
+};
+
+struct prelink_conflict
+{
+ struct prelink_conflict *next;
+ struct prelink_conflict *next2;
+ /* Object which it was relocated to. */
+ union
+ {
+ struct prelink_entry *ent;
+ struct prelink_tls *tls;
+ } lookup,
+ /* Object which the relocation was prelinked to. */
+ conflict;
+ /* Offset from start of owner to owner's symbol. */
+ GElf_Addr symoff;
+ /* Value it has in lookup.ent. */
+ GElf_Addr lookupval;
+ /* Value it has in conflict.ent. */
+ GElf_Addr conflictval;
+ int reloc_class;
+ unsigned char used;
+ unsigned char ifunc;
+ char * symname;
+};
+
+struct prelink_conflicts
+{
+ struct prelink_conflict *first;
+ struct prelink_conflict **hash;
+ struct prelink_conflict **hash2;
+ size_t count;
+};
+
+#define conflict_lookup_value(cfl) \
+ (((cfl)->reloc_class != RTYPE_CLASS_TLS ? (cfl)->lookup.ent->base : 0) \
+ + (cfl)->lookupval)
+
+struct prelink_info
+{
+ DSO *dso;
+ DSO **dsos;
+ struct prelink_entry *ent;
+ struct prelink_symbol *symbols;
+ struct prelink_conflicts *conflicts;
+ struct prelink_conflicts *curconflicts;
+ struct prelink_tls *tls, *curtls;
+ const char **sonames;
+ char *dynbss, *sdynbss;
+ GElf_Addr dynbss_base, sdynbss_base;
+ size_t dynbss_size, sdynbss_size, symtab_entsize;
+ int symbol_count;
+ GElf_Sym *symtab;
+ GElf_Rela *conflict_rela;
+ size_t conflict_rela_alloced, conflict_rela_size;
+ GElf_Addr symtab_start, symtab_end;
+ GElf_Addr (*resolve) (struct prelink_info *info, GElf_Word r_sym,
+ int reloc_type);
+ struct prelink_entry *resolveent;
+ struct prelink_tls *resolvetls;
+};
+
+int prelink_prepare (DSO *dso);
+int prelink (DSO *dso, struct prelink_entry *ent);
+int prelink_init_cache (void);
+int prelink_load_cache (void);
+int prelink_print_cache (void);
+int prelink_save_cache (int do_warn);
+struct prelink_entry *
+ prelink_find_entry (const char *filename, const struct stat64 *stp,
+ int insert);
+struct prelink_conflict *
+ prelink_conflict (struct prelink_info *info, GElf_Word r_sym,
+ int reloc_type);
+GElf_Rela *prelink_conflict_add_rela (struct prelink_info *info);
+int prelink_get_relocations (struct prelink_info *info);
+int prelink_build_conflicts (struct prelink_info *info);
+int update_dynamic_tags (DSO *dso, GElf_Shdr *shdr, GElf_Shdr *old_shdr,
+ struct section_move *move);
+int prelink_exec (struct prelink_info *info);
+int prelink_set_checksum (DSO *dso);
+int is_ldso_soname (const char *soname);
+
+int prelink_undo (DSO *dso);
+
+int prelink_verify (const char *filename);
+ssize_t send_file (int outfd, int infd, off_t *poff, size_t count);
+
+int gather_object (const char *dir, int deref, int onefs);
+int read_config (const char *config);
+int gather_config (void);
+int gather_check_libs (void);
+int add_to_blacklist (const char *name, int deref, int onefs);
+int blacklist_from_config (void);
+
+FILE *execve_open (const char *path, char *const argv[], char *const envp[]);
+int execve_close (FILE *f);
+
+int remove_redundant_cxx_conflicts (struct prelink_info *info);
+int get_relocated_mem (struct prelink_info *info, DSO *dso, GElf_Addr addr,
+ char *buf, GElf_Word size, GElf_Addr dest_addr);
+
+int layout_libs (void);
+
+void prelink_all (void);
+
+int undo_all (void);
+
+char *prelink_canonicalize (const char *name, struct stat64 *stp);
+
+extern const char *dynamic_linker;
+extern const char *ld_library_path;
+extern const char *prelink_cache;
+extern const char *prelink_conf;
+extern const char *undo_output;
+extern int all;
+extern int force;
+extern int random_base;
+extern int conserve_memory;
+extern int verbose;
+extern int dry_run;
+extern int libs_only;
+extern int enable_cxx_optimizations;
+extern int exec_shield;
+extern int undo;
+extern int verify;
+extern int print_cache;
+enum verify_method_t { VERIFY_CONTENT, VERIFY_MD5, VERIFY_SHA };
+extern enum verify_method_t verify_method;
+extern int quick;
+extern long long seed;
+extern GElf_Addr mmap_reg_start, mmap_reg_end, layout_page_size;
+extern char *ld_preload;
+
+extern const char *sysroot;
+
+extern int allow_bad_textrel;
+
+int wrap_readlink (const char *path, char *buf, int len);
+int wrap_lstat64 (const char *file, struct stat64 *buf);
+int wrap_stat64 (const char *file, struct stat64 *buf);
+int wrap_open (const char *file, int mode, ...);
+int wrap_access (const char *file, int mode);
+int wrap_rename (const char *old, const char *new);
+int wrap_link (const char *old, const char *new);
+int wrap_nftw64 (const char *dir, __nftw64_func_t func,
+ int descriptors, int flag);
+int wrap_utime (const char *file, struct utimbuf *file_times);
+int wrap_mkstemp (char *filename);
+int wrap_unlink (const char *filename);
+ssize_t wrap_listxattr (const char *path, char *list, size_t size);
+ssize_t wrap_getxattr (const char *path, const char *name, void *value,
+ size_t size);
+int wrap_setxattr (const char *path, const char *name, const void *value,
+ size_t size, int flags);
+int wrap_glob (const char *pattern, int flags,
+ int (*errfunc) (const char *epath, int eerrno),
+ glob_t *pglob);
+
+char *sysroot_file_name (const char *name, int allow_last_link);
+
+extern const char *prelink_rtld;
+
+#endif /* PRELINK_H */