1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/unix/elfhack/inject.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,52 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include <stdint.h> 1.9 +#include <elf.h> 1.10 + 1.11 +/* The Android NDK headers define those */ 1.12 +#undef Elf_Ehdr 1.13 +#undef Elf_Addr 1.14 + 1.15 +#if defined(__LP64__) 1.16 +#define Elf_Ehdr Elf64_Ehdr 1.17 +#define Elf_Addr Elf64_Addr 1.18 +#else 1.19 +#define Elf_Ehdr Elf32_Ehdr 1.20 +#define Elf_Addr Elf32_Addr 1.21 +#endif 1.22 + 1.23 +extern __attribute__((visibility("hidden"))) void original_init(int argc, char **argv, char **env); 1.24 + 1.25 +extern __attribute__((visibility("hidden"))) Elf32_Rel relhack[]; 1.26 +extern __attribute__((visibility("hidden"))) Elf_Ehdr elf_header; 1.27 + 1.28 +static inline __attribute__((always_inline)) 1.29 +void do_relocations(void) 1.30 +{ 1.31 + Elf32_Rel *rel; 1.32 + Elf_Addr *ptr, *start; 1.33 + for (rel = relhack; rel->r_offset; rel++) { 1.34 + start = (Elf_Addr *)((intptr_t)&elf_header + rel->r_offset); 1.35 + for (ptr = start; ptr < &start[rel->r_info]; ptr++) 1.36 + *ptr += (intptr_t)&elf_header; 1.37 + } 1.38 +} 1.39 + 1.40 +__attribute__((section(".text._init_noinit"))) 1.41 +int init_noinit(int argc, char **argv, char **env) 1.42 +{ 1.43 + do_relocations(); 1.44 + return 0; 1.45 +} 1.46 + 1.47 +__attribute__((section(".text._init"))) 1.48 +int init(int argc, char **argv, char **env) 1.49 +{ 1.50 + do_relocations(); 1.51 + original_init(argc, argv, env); 1.52 + // Ensure there is no tail-call optimization, avoiding the use of the 1.53 + // B.W instruction in Thumb for the call above. 1.54 + return 0; 1.55 +}