1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 13 Dec '05 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Linker no longer used - apart from mymalloc(). 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Instead, simply compile and link switchback.c with test_xxx.c, e.g.: 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ./> (cd .. && make EXTRA_CFLAGS="-m64" libvex_ppc64_linux.a) && gcc -m64 -Wall -O -g -o switchback switchback.c linker.c ../libvex_ppc64_linux.a test_bzip2.c 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdlib.h> 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h> 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <assert.h> 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/types.h> 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/stat.h> 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <unistd.h> 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <elf.h> 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <fcntl.h> 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <string.h> 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//#include <malloc.h> 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "linker.h" 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_basictypes.h" 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define IF_DEBUG(x,y) /* */ 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int debug_linker = 0; 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__x86_64__) 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define x86_64_TARGET_ARCH 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(__i386__) 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define i386_TARGET_ARCH 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined (__powerpc__) 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define ppc32_TARGET_ARCH 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# error "Unknown arch" 38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALLOC_MAX 10000000 43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HChar calloc_area[CALLOC_MAX]; 44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt calloc_used = 0; 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void* calloc_below2G ( Int n, Int m ) 46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* p; 48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while ((calloc_used % 16) > 0) calloc_used++; 50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(calloc_used + n*m < CALLOC_MAX); 51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = &calloc_area[calloc_used]; 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < n*m; i++) 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov calloc_area[calloc_used+i] = 0; 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov calloc_used += n*m; 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return p; 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define MYMALLOC_MAX 50*1000*1000 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HChar mymalloc_area[MYMALLOC_MAX]; 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt mymalloc_used = 0; 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid* mymalloc ( Int n ) 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* p; 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__powerpc64__) 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while ((ULong)(mymalloc_area+mymalloc_used) & 0xFFF) 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while ((UInt)(mymalloc_area+mymalloc_used) & 0xFFF) 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mymalloc_used++; 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(mymalloc_used+n < MYMALLOC_MAX); 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = (void*)(&mymalloc_area[mymalloc_used]); 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mymalloc_used += n; 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // printf("mymalloc(%d) = %p\n", n, p); 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return p; 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid myfree ( void* p ) 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// TYPES 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FALSE 0 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TRUE 1 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef enum { OBJECT_LOADED, OBJECT_RESOLVED } OStatus; 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_FIXUP_PAGES 1 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Indication of section kinds for loaded objects. Needed by 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the GC for deciding whether or not a pointer on the stack 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov is a code pointer. 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov enum { SECTIONKIND_CODE_OR_RODATA, 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SECTIONKIND_RWDATA, 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SECTIONKIND_OTHER, 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SECTIONKIND_NOINFOAVAIL } 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SectionKind; 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct _Section { 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* start; 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* end; 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SectionKind kind; 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct _Section* next; 121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Section; 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct _ProddableBlock { 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* start; 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int size; 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct _ProddableBlock* next; 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ProddableBlock; 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Top-level structure for an object module. One of these is allocated 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * for each object file in use. 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef struct _ObjectCode { 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov OStatus status; 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* fileName; 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int fileSize; 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */ 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* An array containing ptrs to all the symbol names copied from 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov this object into the global symbol hash table. This is so that 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov we know which parts of the latter mapping to nuke when this 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov object is removed from the system. */ 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char** symbols; 146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int n_symbols; 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* ptr to malloc'd lump of memory holding the obj file */ 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* image; 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Fixup area for long-distance jumps. */ 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* fixup; 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int fixup_used; 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int fixup_size; 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* The section-kind entries for this object module. Linked 157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov list. */ 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Section* sections; 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* A private hash table for local symbols. */ 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* HashTable* */ void* lochash; 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Allow a chain of these things */ 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct _ObjectCode * next; 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* SANITY CHECK ONLY: a list of the only memory regions which may 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov safely be prodded during relocation. Any attempt to prod 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov outside one of these is an error in the linker. */ 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ProddableBlock* proddables; 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} ObjectCode; 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Define a set of types which can be used for both ELF32 and ELF64 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if VEX_HOST_WORDSIZE == 8 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELFCLASS ELFCLASS64 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Addr Elf64_Addr 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Word Elf64_Word 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Sword Elf64_Sword 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Ehdr Elf64_Ehdr 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Phdr Elf64_Phdr 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Shdr Elf64_Shdr 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Sym Elf64_Sym 186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Rel Elf64_Rel 187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Rela Elf64_Rela 188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_ST_TYPE ELF64_ST_TYPE 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_ST_BIND ELF64_ST_BIND 190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_R_TYPE ELF64_R_TYPE 191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_R_SYM ELF64_R_SYM 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELFCLASS ELFCLASS32 194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Addr Elf32_Addr 195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Word Elf32_Word 196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Sword Elf32_Sword 197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Ehdr Elf32_Ehdr 198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Phdr Elf32_Phdr 199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Shdr Elf32_Shdr 200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Sym Elf32_Sym 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Rel Elf32_Rel 202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define Elf_Rela Elf32_Rela 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifndef ELF_ST_TYPE 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_ST_TYPE ELF32_ST_TYPE 205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifndef ELF_ST_BIND 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_ST_BIND ELF32_ST_BIND 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifndef ELF_R_TYPE 210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_R_TYPE ELF32_R_TYPE 211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifndef ELF_R_SYM 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define ELF_R_SYM ELF32_R_SYM 214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// PARANOIA 225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ----------------------------------------------------------------------- 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Sanity checking. For each ObjectCode, maintain a list of address ranges 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * which may be prodded during relocation, and abort if we try and write 229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * outside any of these. 230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void addProddableBlock ( ObjectCode* oc, void* start, int size ) 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ProddableBlock* pb 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov = mymalloc(sizeof(ProddableBlock)); 235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker) 236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "aPB oc=%p %p %d (%p .. %p)\n", oc, start, size, 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov start, ((char*)start)+size-1 ); 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(size > 0); 239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pb->start = start; 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pb->size = size; 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pb->next = oc->proddables; 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->proddables = pb; 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void checkProddableBlock ( ObjectCode* oc, void* addr ) 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ProddableBlock* pb; 248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (pb = oc->proddables; pb != NULL; pb = pb->next) { 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* s = (char*)(pb->start); 250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* e = s + pb->size - 1; 251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* a = (char*)addr; 252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Assumes that the biggest fixup involves a 4-byte write. This 253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov probably needs to be changed to 8 (ie, +7) on 64-bit 254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov plats. */ 255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (a >= s && (a+3) <= e) return; 256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, 258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "checkProddableBlock: invalid fixup %p in runtime linker\n", 259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr); 260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// String->Addr mappings 270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { char* mp_name; void* mp_addr; } 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Maplet; 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int sm_size; 278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int sm_used; 279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Maplet* maplets; 280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov StringMap; 282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic StringMap* new_StringMap ( void ) 284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov StringMap* sm = mymalloc(sizeof(StringMap)); 286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->sm_size = 10; 287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->sm_used = 0; 288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->maplets = mymalloc(10 * sizeof(Maplet)); 289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return sm; 290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void delete_StringMap ( StringMap* sm ) 293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(sm->maplets != NULL); 295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov myfree(sm->maplets); 296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->maplets = NULL; 297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov myfree(sm); 298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void ensure_StringMap ( StringMap* sm ) 301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Maplet* mp2; 304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(sm->maplets != NULL); 305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (sm->sm_used < sm->sm_size) 306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return; 307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->sm_size *= 2; 308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mp2 = mymalloc(sm->sm_size * sizeof(Maplet)); 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < sm->sm_used; i++) 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mp2[i] = sm->maplets[i]; 311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov myfree(sm->maplets); 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->maplets = mp2; 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void* search_StringMap ( StringMap* sm, char* name ) 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < sm->sm_used; i++) 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0 == strcmp(name, sm->maplets[i].mp_name)) 320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return sm->maplets[i].mp_addr; 321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return NULL; 322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void addto_StringMap ( StringMap* sm, char* name, void* addr ) 325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ensure_StringMap(sm); 327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->maplets[sm->sm_used].mp_name = name; 328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->maplets[sm->sm_used].mp_addr = addr; 329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sm->sm_used++; 330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void paranoid_addto_StringMap ( StringMap* sm, char* name, void* addr ) 333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) 335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "paranoid_addto_StringMap(%s,%p)\n", name, addr); 336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (search_StringMap(sm,name) != NULL) { 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "duplicate: paranoid_addto_StringMap(%s,%p)\n", name, addr); 338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addto_StringMap(sm,name,addr); 341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Top-level linker control. 349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovStringMap* global_symbol_table = NULL; 351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovObjectCode* global_object_list = NULL; 352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void initLinker ( void ) 354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (global_symbol_table != NULL) 356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return; 357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov global_symbol_table = new_StringMap(); 358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// SYMBOL TABLE(s) 367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ----------------------------------------------------------------- 369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * lookup a symbol in the global symbol table 370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid * lookupSymbol( char *lbl ) 373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void *val; 375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov initLinker() ; 376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(global_symbol_table != NULL); 377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = search_StringMap(global_symbol_table, lbl); 378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return val; 379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// HELPERS 387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Generic ELF functions 390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic char * 393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovfindElfSection ( void* objImage, Elf_Word sh_type ) 394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* ehdrC = (char*)objImage; 396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC; 397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Shdr* shdr = (Elf_Shdr*)(ehdrC + ehdr->e_shoff); 398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* ptr = NULL; 400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < ehdr->e_shnum; i++) { 403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[i].sh_type == sh_type 404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Ignore the section header's string table. */ 405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && i != ehdr->e_shstrndx 406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Ignore string tables named .stabstr, as they contain 407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov debugging info. */ 408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8) 409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ) { 410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ptr = ehdrC + shdr[i].sh_offset; 411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ptr; 415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef arm_TARGET_ARCH 418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovchar* alloc_fixup_bytes ( ObjectCode* oc, int nbytes ) 420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* res; 422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(nbytes % 4 == 0); 423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(nbytes > 0); 424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = &(oc->fixup[oc->fixup_used]); 425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fixup_used += nbytes; 426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (oc->fixup_used >= oc->fixup_size) { 427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "fixup area too small for %s\n", oc->fileName); 428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return res; 431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// RESOLVE 440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid* lookup_magic_hacks ( char* sym ) 443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0==strcmp(sym, "printf")) return (void*)(&printf); 445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return NULL; 446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef arm_TARGET_ARCH 449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid arm_notify_new_code ( char* start, int length ) 451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm __volatile ("mov r1, %0\n\t" 453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mov r2, %1\n\t" 454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "mov r3, %2\n\t" 455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "swi 0x9f0002\n\t" 456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : 457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "ir" (start), "ir" (length), "ir" (0) ); 458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid gen_armle_goto ( char* fixup, char* dstP ) 463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word w = (Elf_Word)dstP; 465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* 466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 2 .text 467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3 0000 04F01FE5 ldr pc, value 468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4 0004 44332211 value: .word 0x11223344 469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"at %p generating jump to %p\n", fixup, dstP ); 471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fixup[0] = 0x04; fixup[1] = 0xF0; fixup[2] = 0x1F; fixup[3] = 0xE5; 472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fixup[4] = w & 0xFF; w >>= 8; 473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fixup[5] = w & 0xFF; w >>= 8; 474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fixup[6] = w & 0xFF; w >>= 8; 475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fixup[7] = w & 0xFF; w >>= 8; 476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov arm_notify_new_code(fixup, 8); 477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* arm_TARGET_ARCH */ 479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef ppc32_TARGET_ARCH 482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void invalidate_icache(void *ptr, int nbytes) 483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long startaddr = (unsigned long) ptr; 485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long endaddr = startaddr + nbytes; 486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long addr; 487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned long cls = 16; //VG_(cache_line_size); 488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov startaddr &= ~(cls - 1); 490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (addr = startaddr; addr < endaddr; addr += cls) 491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("dcbst 0,%0" : : "r" (addr)); 492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("sync"); 493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (addr = startaddr; addr < endaddr; addr += cls) 494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("icbi 0,%0" : : "r" (addr)); 495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("sync; isync"); 496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt compute_ppc_HA ( UInt x ) { 499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0xFFFF & ( (x >> 16) + ((x & 0x8000) ? 1 : 0) ); 500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt compute_ppc_LO ( UInt x ) { 502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0xFFFF & x; 503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt compute_ppc_HI ( UInt x ) { 505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0xFFFF & (x >> 16); 506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* ppc32_TARGET_ARCH */ 508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Do ELF relocations which lack an explicit addend. All x86-linux 511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov relocations appear to be of this form. */ 512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int 513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovdo_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC, 514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Shdr* shdr, int shnum, 515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Sym* stab, char* strtab ) 516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int j; 518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char *symbol = NULL; 519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word* targ; 520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Rel* rtab = (Elf_Rel*) (ehdrC + shdr[shnum].sh_offset); 521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int nent = shdr[shnum].sh_size / sizeof(Elf_Rel); 522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int target_shndx = shdr[shnum].sh_info; 523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int symtab_shndx = shdr[shnum].sh_link; 524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset); 526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov targ = (Elf_Word*)(ehdrC + shdr[ target_shndx ].sh_offset); 527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov IF_DEBUG(linker,belch( "relocations for section %d using symtab %d", 528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov target_shndx, symtab_shndx )); 529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (j = 0; j < nent; j++) { 531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr offset = rtab[j].r_offset; 532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr info = rtab[j].r_info; 533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr P = ((Elf_Addr)targ) + offset; 535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word* pP = (Elf_Word*)P; 536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr A = *pP; 537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr S; 538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr value; 539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)", 541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov j, (void*)offset, (void*)info )); 542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!info) { 543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov IF_DEBUG(linker,belch( " ZERO" )); 544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = 0; 545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Sym sym = stab[ELF_R_SYM(info)]; 547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* First see if it is a local symbol. */ 548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) { 549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Yes, so we can get the address directly from the ELF symbol 550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov table. */ 551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name; 552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = (Elf_Addr) 553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ehdrC + shdr[ sym.st_shndx ].sh_offset 554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov + stab[ELF_R_SYM(info)].st_value); 555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* No, so look up the name in our global table. */ 558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov symbol = strtab + sym.st_name; 559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = (Elf_Addr)lookupSymbol( symbol ); 560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!S) { 562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = (Elf_Addr)lookup_magic_hacks(symbol); 563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!S) { 565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: unknown symbol `%s'\n", 566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fileName, symbol); 567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) 570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "\n`%s' resolves to %p\n", symbol, (void*)S ); 571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) 574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "Reloc: P = %p S = %p A = %p\n", 575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void*)P, (void*)S, (void*)A ); 576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov checkProddableBlock ( oc, pP ); 577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov value = S + A; 579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (ELF_R_TYPE(info)) { 581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# ifdef i386_TARGET_ARCH 582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_386_32: *pP = value; break; 583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_386_PC32: *pP = value - P; break; 584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# ifdef arm_TARGET_ARCH 586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_ARM_PC24: { 587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word w, delta, deltaTop8; 588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Generate a jump sequence into the fixup area 589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov and branch to that instead. */ 590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* fixup = alloc_fixup_bytes(oc, 8); 591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* First of all, figure out where we're really trying to 592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov jump to. */ 593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // compensate for pc+8 bias 594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word real_dst = (A & 0x00FFFFFF) + 2; 595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // sign-extend 24-to-32 of real_dst 596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (real_dst & 0x00800000) 597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov real_dst |= 0xFF000000; 598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov real_dst &= 0x00FFFFFF; 600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov real_dst <<= 2; 602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov real_dst += S; 603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gen_armle_goto(fixup, (char*)real_dst); 605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Delta is in bytes .. */ 607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov delta = (((Elf_Word)fixup) - ((Elf_Word)pP) - 8); 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov deltaTop8 = (delta >> 24) & 0xFF; 609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (deltaTop8 != 0 && deltaTop8 != 0xFF) { 610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"R_ARM_PC24: out of range delta 0x%x for %s\n", 611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov delta, symbol); 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov delta >>= 2; 615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w = *pP; 616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w &= 0xFF000000; 617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w |= (0x00FFFFFF & delta ); 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = w; 619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_ARM_ABS32: 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = value; 623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%s: unhandled ELF relocation(Rel) type %d\n\n", 628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fileName, (Int)ELF_R_TYPE(info)); 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 1; 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Do ELF relocations for which explicit addends are supplied. 637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sparc-solaris relocations appear to be of this form. */ 638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovdo_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC, 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Shdr* shdr, int shnum, 641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Sym* stab, char* strtab ) 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int j; 644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char *symbol; 645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr targ; 646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Rela* rtab = (Elf_Rela*) (ehdrC + shdr[shnum].sh_offset); 647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int nent = shdr[shnum].sh_size / sizeof(Elf_Rela); 648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int target_shndx = shdr[shnum].sh_info; 649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int symtab_shndx = shdr[shnum].sh_link; 650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset); 652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov targ = (Elf_Addr) (ehdrC + shdr[ target_shndx ].sh_offset); 653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov IF_DEBUG(linker,belch( "relocations for section %d using symtab %d", 654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov target_shndx, symtab_shndx )); 655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (j = 0; j < nent; j++) { 657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(DEBUG) || defined(sparc_TARGET_ARCH) \ 658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || defined(ia64_TARGET_ARCH) \ 659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || defined(x86_64_TARGET_ARCH) \ 660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || defined(ppc32_TARGET_ARCH) 661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* This #ifdef only serves to avoid unused-var warnings. */ 662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr offset = rtab[j].r_offset; 663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr P = targ + offset; 664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr info = rtab[j].r_info; 666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr A = rtab[j].r_addend; 667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr S =0; 668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr value; 669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(sparc_TARGET_ARCH) 670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word* pP = (Elf_Word*)P; 671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word w1, w2; 672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(ia64_TARGET_ARCH) 674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf64_Xword *pP = (Elf64_Xword *)P; 675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Addr addr; 676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(x86_64_TARGET_ARCH) 678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong* pP = (ULong*)P; 679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(ppc32_TARGET_ARCH) 681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int sI, sI2; 682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Word* pP = (Elf_Word*)P; 683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ", 686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov j, (void*)offset, (void*)info, 687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void*)A )); 688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!info) { 689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov IF_DEBUG(linker,belch( " ZERO" )); 690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = 0; 691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Sym sym = stab[ELF_R_SYM(info)]; 693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* First see if it is a local symbol. */ 694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) { 695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Yes, so we can get the address directly from the ELF symbol 696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov table. */ 697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name; 698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = (Elf_Addr) 699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ehdrC + shdr[ sym.st_shndx ].sh_offset 700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov + stab[ELF_R_SYM(info)].st_value); 701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef ELF_FUNCTION_DESC 702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Make a function descriptor for this function */ 703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (S && ELF_ST_TYPE(sym.st_info) == STT_FUNC) { 704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = allocateFunctionDesc(S + A); 705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov A = 0; 706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* No, so look up the name in our global table. */ 710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov symbol = strtab + sym.st_name; 711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov S = (Elf_Addr)lookupSymbol( symbol ); 712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef ELF_FUNCTION_DESC 714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* If a function, already a function descriptor - we would 715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov have to copy it to add an offset. */ 716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (S && (ELF_ST_TYPE(sym.st_info) == STT_FUNC) && (A != 0)) 717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov belch("%s: function %s with addend %p", oc->fileName, symbol, (void *)A); 718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!S) { 721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: unknown symbol `%s'\n", oc->fileName, symbol); 722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) 725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "`%s' resolves to %p\n", symbol, (void*)S ); 726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf ( stderr, "Reloc: offset = %p P = %p S = %p A = %p\n", 730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void*)offset, (void*)P, (void*)S, (void*)A ); 731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* checkProddableBlock ( oc, (void*)P ); */ 734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov value = S + A; 736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (ELF_R_TYPE(info)) { 738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(sparc_TARGET_ARCH) 739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_SPARC_WDISP30: 740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w1 = *pP & 0xC0000000; 741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w2 = (Elf_Word)((value - P) >> 2); 742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ASSERT((w2 & 0xC0000000) == 0); 743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w1 |= w2; 744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = w1; 745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_SPARC_HI22: 747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w1 = *pP & 0xFFC00000; 748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w2 = (Elf_Word)(value >> 10); 749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ASSERT((w2 & 0xFFC00000) == 0); 750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w1 |= w2; 751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = w1; 752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_SPARC_LO10: 754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w1 = *pP & ~0x3FF; 755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w2 = (Elf_Word)(value & 0x3FF); 756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ASSERT((w2 & ~0x3FF) == 0); 757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w1 |= w2; 758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = w1; 759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* According to the Sun documentation: 761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov R_SPARC_UA32 762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov This relocation type resembles R_SPARC_32, except it refers to an 763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unaligned word. That is, the word to be relocated must be treated 764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov as four separate bytes with arbitrary alignment, not as a word 765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov aligned according to the architecture requirements. 766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (JRS: which means that freeloading on the R_SPARC_32 case 768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov is probably wrong, but hey ...) 769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_SPARC_UA32: 771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_SPARC_32: 772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w2 = (Elf_Word)value; 773b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = w2; 774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(ia64_TARGET_ARCH) 777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_DIR64LSB: 778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_FPTR64LSB: 779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = value; 780b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_PCREL64LSB: 782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = value - P; 783b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_SEGREL64LSB: 785b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr = findElfSegment(ehdrC, value); 786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *pP = value - addr; 787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_GPREL22: 789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ia64_reloc_gprel22(P, value); 790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_LTOFF22: 792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_LTOFF22X: 793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_LTOFF_FPTR22: 794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr = allocateGOTEntry(value); 795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ia64_reloc_gprel22(P, addr); 796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_PCREL21B: 798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ia64_reloc_pcrel21(P, S, oc); 799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_IA64_LDXMOV: 801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* This goes with R_IA64_LTOFF22X and points to the load to 802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov convert into a move. We don't implement relaxation. */ 803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(x86_64_TARGET_ARCH) 806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_X86_64_64: /* 1 *//* Direct 64 bit */ 807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((ULong*)pP) = (ULong)(S + A); 808b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_X86_64_PC32: /* 2 *//* PC relative 32 bit signed */ 810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) = (UInt)(S + A - P); 811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_X86_64_32: /* 10 *//* Direct 32 bit zero extended */ 813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) = (UInt)(S + A); 814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_X86_64_32S: /* 11 *//* Direct 32 bit sign extended */ 816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) = (UInt)(S + A); 817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(ppc32_TARGET_ARCH) 820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_PPC_ADDR32: /* 1 *//* 32bit absolute address */ 821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) = S+A; 822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache(pP,4); 823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_PPC_ADDR16_LO: /* 4 *//* lower 16bit of absolute address */ 825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) &= 0x0000FFFF; 826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) |= 0xFFFF0000 & (compute_ppc_LO(S+A) << 16); 827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache(pP,4); 828b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_PPC_ADDR16_HA: /* 6 *//* adjusted high 16bit */ 830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) &= 0x0000FFFF; 831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) |= 0xFFFF0000 & (compute_ppc_HA(S+A) << 16); 832b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache(pP,4); 833b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 834b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_PPC_REL24: /* 10 *//* PC relative 26 bit */ 835b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sI = S+A-P; 836b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sI >>= 2; 837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* the top 9 bits of sI must be the same (all 0s or 838b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov all 1s) for this to be valid; else we have to fail. */ 839b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sI2 = sI >> 23; /* 23 == 32 - 9 */ 840b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (sI2 != 0 && sI2 != 0xFFFFFFFF) { 841b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "%s: R_PPC_REL24 relocation failed\n", oc->fileName ); 842b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 843b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 844b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) &= ~(0x00FFFFFF << 2); 845b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) |= (0xFFFFFF & sI) << 2; 846b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache(pP,4); 847b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 848b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case R_PPC_REL32: /* 26 */ 849b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *((UInt*)pP) = S+A-P; 850b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache(pP,4); 851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 854b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, 855b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%s: unhandled ELF relocation(RelA) type %d\n", 856b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fileName, (Int)ELF_R_TYPE(info)); 857b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 858b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 859b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 860b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 861b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 1; 862b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 863b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 864b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 865b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int 866b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovocResolve_ELF ( ObjectCode* oc ) 867b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 868b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char *strtab; 869b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int shnum, ok; 870b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Sym* stab = NULL; 871b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* ehdrC = (char*)(oc->image); 872b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Ehdr* ehdr = (Elf_Ehdr*) ehdrC; 873b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); 874b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 875b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 876b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* first find "the" symbol table */ 877b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov stab = (Elf_Sym*) findElfSection ( ehdrC, SHT_SYMTAB ); 878b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 879b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* also go find the string table */ 880b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov strtab = findElfSection ( ehdrC, SHT_STRTAB ); 881b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 882b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (stab == NULL || strtab == NULL) { 883b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: can't find string or symbol table\n", oc->fileName); 884b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 885b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 886b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 887b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Process the relocation sections. */ 888b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (shnum = 0; shnum < ehdr->e_shnum; shnum++) { 889b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 890b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Skip sections called ".rel.stab". These appear to contain 891b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov relocation entries that, when done, make the stabs debugging 892b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov info point at the right places. We ain't interested in all 893b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov dat jazz, mun. */ 894b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0 == memcmp(".rel.stab", sh_strtab + shdr[shnum].sh_name, 9)) 895b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov continue; 896b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 897b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[shnum].sh_type == SHT_REL ) { 898b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ok = do_Elf_Rel_relocations ( oc, ehdrC, shdr, 899b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov shnum, stab, strtab ); 900b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!ok) return ok; 901b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 902b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 903b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[shnum].sh_type == SHT_RELA) { 904b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ok = do_Elf_Rela_relocations ( oc, ehdrC, shdr, 905b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov shnum, stab, strtab ); 906b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!ok) return ok; 907b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 908b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 909b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 910b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Free the local symbol table; we won't need it again. */ 911b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov delete_StringMap(oc->lochash); 912b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->lochash = NULL; 913b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 914b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 1; 915b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 916b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 917b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 918b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 919b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 921b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 922b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// VERIFY 923b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 924b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int 925b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovocVerifyImage_ELF ( ObjectCode* oc ) 926b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 927b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Shdr* shdr; 928b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Sym* stab; 929b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i, j, nent, nstrtab, nsymtabs; 930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* sh_strtab; 931b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* strtab; 932b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 933b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* ehdrC = (char*)(oc->image); 934b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC; 935b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 936b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || 937b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdr->e_ident[EI_MAG1] != ELFMAG1 || 938b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdr->e_ident[EI_MAG2] != ELFMAG2 || 939b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdr->e_ident[EI_MAG3] != ELFMAG3) { 940b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: not an ELF object\n", oc->fileName); 941b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 942b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 943b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 944b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ehdr->e_ident[EI_CLASS] != ELFCLASS) { 945b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: unsupported ELF format\n", oc->fileName); 946b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 947b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 948b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 949b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) { 950b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker) 951b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "Is little-endian\n" ); 952b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else 953b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) { 954b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker) 955b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "Is big-endian\n" ); 956b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 957b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: unknown endiannness\n", oc->fileName); 958b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 959b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 960b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 961b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ehdr->e_type != ET_REL) { 962b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: not a relocatable object (.o) file\n", oc->fileName); 963b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 964b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 965b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker) 966b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "Is a relocatable object (.o) file\n" ); 967b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 968b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker) 969b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "Architecture is " ); 970b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (ehdr->e_machine) { 971b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case EM_386: if (debug_linker) fprintf(stderr, "x86\n" ); break; 972b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case EM_SPARC: if (debug_linker) fprintf(stderr, "sparc\n" ); break; 973b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case EM_ARM: if (debug_linker) fprintf(stderr, "arm\n" ); break; 974b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef EM_IA_64 975b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case EM_IA_64: if (debug_linker) fprintf(stderr, "ia64\n" ); break; 976b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 977b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case EM_X86_64: if (debug_linker) fprintf(stderr, "x86_64\n" ); break; 978b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case EM_PPC: if (debug_linker) fprintf(stderr, "ppc\n" ); break; 979b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: if (debug_linker) fprintf(stderr, "unknown\n" ); 980b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: unknown architecture\n", oc->fileName); 981b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 982b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 983b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 984b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, 985b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "\nSection header table: start %lld, n_entries %d, ent_size %d\n", 986b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Long)ehdr->e_shoff, 987b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdr->e_shnum, ehdr->e_shentsize ); 988b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 989b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert (ehdr->e_shentsize == sizeof(Elf_Shdr)); 990b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 991b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); 992b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 993b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ehdr->e_shstrndx == SHN_UNDEF) { 994b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: no section header string table\n", oc->fileName); 995b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 996b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 997b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) 998b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "Section header string table is section %d\n", 999b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdr->e_shstrndx); 1000b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 1001b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1002b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1003b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < ehdr->e_shnum; i++) { 1004b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "%2d: ", i ); 1005b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ); 1006b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ); 1007b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ); 1008b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, " (%p .. %p) ", 1009b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdrC + shdr[i].sh_offset, 1010b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1); 1011b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1012b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[i].sh_type == SHT_REL) { 1013b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "Rel " ); 1014b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else if (shdr[i].sh_type == SHT_RELA) { 1015b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "RelA " ); 1016b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 1017b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr," "); 1018b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1019b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (sh_strtab) { 1020b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "sname=%s\n", 1021b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sh_strtab + shdr[i].sh_name ); 1022b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1023b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1024b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1025b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "\nString tables\n" ); 1026b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov strtab = NULL; 1027b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nstrtab = 0; 1028b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < ehdr->e_shnum; i++) { 1029b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[i].sh_type == SHT_STRTAB 1030b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Ignore the section header's string table. */ 1031b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && i != ehdr->e_shstrndx 1032b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Ignore string tables named .stabstr, as they contain 1033b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov debugging info. */ 1034b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8) 1035b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ) { 1036b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) 1037b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr," section %d is a normal string table\n", i ); 1038b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov strtab = ehdrC + shdr[i].sh_offset; 1039b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nstrtab++; 1040b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1041b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1042b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (nstrtab != 1) { 1043b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: no string tables, or too many\n", oc->fileName); 1044b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 1045b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1046b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1047b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nsymtabs = 0; 1048b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "\nSymbol tables\n" ); 1049b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < ehdr->e_shnum; i++) { 1050b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[i].sh_type != SHT_SYMTAB) continue; 1051b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "section %d is a symbol table\n", i ); 1052b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nsymtabs++; 1053b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset); 1054b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nent = shdr[i].sh_size / sizeof(Elf_Sym); 1055b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, 1056b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov " number of entries is apparently %d (%lld rem)\n", 1057b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nent, 1058b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Long)(shdr[i].sh_size % sizeof(Elf_Sym)) 1059b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); 1060b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0 != shdr[i].sh_size % sizeof(Elf_Sym)) { 1061b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: non-integral number of symbol table entries\n", 1062b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fileName); 1063b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 1064b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1065b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (j = 0; j < nent; j++) { 1066b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, " %2d ", j ); 1067b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, " sec=%-5d size=%-3d val=%5p ", 1068b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (int)stab[j].st_shndx, 1069b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (int)stab[j].st_size, 1070b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (char*)stab[j].st_value ); 1071b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1072b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "type=" ); 1073b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (ELF_ST_TYPE(stab[j].st_info)) { 1074b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STT_NOTYPE: if (debug_linker>1) fprintf(stderr, "notype " ); break; 1075b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STT_OBJECT: if (debug_linker>1) fprintf(stderr, "object " ); break; 1076b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STT_FUNC : if (debug_linker>1) fprintf(stderr, "func " ); break; 1077b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STT_SECTION: if (debug_linker>1) fprintf(stderr, "section" ); break; 1078b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STT_FILE: if (debug_linker>1) fprintf(stderr, "file " ); break; 1079b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: if (debug_linker>1) fprintf(stderr, "? " ); break; 1080b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1081b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, " " ); 1082b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1083b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "bind=" ); 1084b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (ELF_ST_BIND(stab[j].st_info)) { 1085b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STB_LOCAL : if (debug_linker>1) fprintf(stderr, "local " ); break; 1086b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STB_GLOBAL: if (debug_linker>1) fprintf(stderr, "global" ); break; 1087b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case STB_WEAK : if (debug_linker>1) fprintf(stderr, "weak " ); break; 1088b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: if (debug_linker>1) fprintf(stderr, "? " ); break; 1089b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1090b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, " " ); 1091b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1092b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ); 1093b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1094b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1095b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1096b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (nsymtabs == 0) { 1097b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: didn't find any symbol tables\n", oc->fileName); 1098b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 1099b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 1; 1102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 1106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 1107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 1108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 1109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// GETNAMES 1110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int 1112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovocGetNames_ELF ( ObjectCode* oc ) 1113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i, j, k, nent; 1115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Sym* stab; 1116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* ehdrC = (char*)(oc->image); 1118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC; 1119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* strtab = findElfSection ( ehdrC, SHT_STRTAB ); 1120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); 1121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 1123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* sec_name; 1124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(global_symbol_table != NULL); 1126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!strtab) { 1128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"%s: no strtab\n", oc->fileName); 1129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 1130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov k = 0; 1133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < ehdr->e_shnum; i++) { 1134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Figure out what kind of section it is. Logic derived from 1135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Figure 1.14 ("Special Sections") of the ELF document 1136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ("Portable Formats Specification, Version 1.1"). */ 1137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Elf_Shdr hdr = shdr[i]; 1138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SectionKind kind = SECTIONKIND_OTHER; 1139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int is_bss = FALSE; 1140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (hdr.sh_type == SHT_PROGBITS 1142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_EXECINSTR)) { 1143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* .text-style section */ 1144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov kind = SECTIONKIND_CODE_OR_RODATA; 1145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 1147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (hdr.sh_type == SHT_PROGBITS 1148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_WRITE)) { 1149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* .data-style section */ 1150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov kind = SECTIONKIND_RWDATA; 1151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 1153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (hdr.sh_type == SHT_PROGBITS 1154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && (hdr.sh_flags & SHF_ALLOC) && !(hdr.sh_flags & SHF_WRITE)) { 1155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* .rodata-style section */ 1156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov kind = SECTIONKIND_CODE_OR_RODATA; 1157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 1159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (hdr.sh_type == SHT_NOBITS 1160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_WRITE)) { 1161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* .bss-style section */ 1162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov kind = SECTIONKIND_RWDATA; 1163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov is_bss = TRUE; 1164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_bss && shdr[i].sh_size > 0) { 1167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* This is a non-empty .bss section. Allocate zeroed space for 1168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov it, and set its .sh_offset field such that 1169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ehdrC + .sh_offset == addr_of_zeroed_space. */ 1170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* zspace = calloc(1, shdr[i].sh_size); 1171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC); 1172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (1) 1173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "BSS section at %p, size %lld\n", 1174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov zspace, (Long)shdr[i].sh_size); 1175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* When loading objects compiled with -g, it seems there are 1178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov relocations in various debug-info sections. So we'd better 1179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tell addProddableBlock to allow those bits to be prodded. */ 1180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //fprintf(stderr, "ZZZZZZZZZZ %s\n", sh_strtab + hdr.sh_name); 1181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sec_name = sh_strtab + shdr[i].sh_name; 1182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (kind == SECTIONKIND_OTHER 1183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && (0 == strcmp(".debug_info", sec_name) 1184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || 0 == strcmp(".debug_line", sec_name) 1185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || 0 == strcmp(".debug_pubnames", sec_name) 1186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || 0 == strcmp(".debug_aranges", sec_name) 1187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || 0 == strcmp(".debug_frame", sec_name))) { 1188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov kind = SECTIONKIND_CODE_OR_RODATA; 1189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* fill in the section info */ 1192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0) { 1193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addProddableBlock(oc, ehdrC + shdr[i].sh_offset, shdr[i].sh_size); 1194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //addSection(oc, kind, ehdrC + shdr[i].sh_offset, 1195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1); 1196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[i].sh_type != SHT_SYMTAB) continue; 1199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* copy stuff into this module's object symbol table */ 1201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset); 1202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nent = shdr[i].sh_size / sizeof(Elf_Sym); 1203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->n_symbols = nent; 1205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->symbols = mymalloc(oc->n_symbols * sizeof(char*)); 1206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (j = 0; j < nent; j++) { 1208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char isLocal = FALSE; /* avoids uninit-var warning */ 1210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* ad = NULL; 1211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* nm = strtab + stab[j].st_name; 1212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int secno = stab[j].st_shndx; 1213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Figure out if we want to add it; if so, set ad to its 1215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov address. Otherwise leave ad == NULL. */ 1216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (secno == SHN_COMMON) { 1218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov isLocal = FALSE; 1219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(__x86_64__) 1220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ad = calloc_below2G(1, stab[j].st_size); 1221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# else 1222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ad = calloc(1, stab[j].st_size); 1223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 1224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // assert( Ptr_to_ULong(ad) < 0xF0000000ULL ); 1225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) 1227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "COMMON symbol, size %lld name %s allocd %p\n", 1228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Long)stab[j].st_size, nm, ad); 1229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Pointless to do addProddableBlock() for this area, 1230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov since the linker should never poke around in it. */ 1231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 1233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ( ( ELF_ST_BIND(stab[j].st_info)==STB_GLOBAL 1234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || ELF_ST_BIND(stab[j].st_info)==STB_LOCAL 1235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ) 1236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* and not an undefined symbol */ 1237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && stab[j].st_shndx != SHN_UNDEF 1238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* and not in a "special section" */ 1239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && stab[j].st_shndx < SHN_LORESERVE 1240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && 1241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* and it's a not a section or string table or anything silly */ 1242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( ELF_ST_TYPE(stab[j].st_info)==STT_FUNC || 1243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ELF_ST_TYPE(stab[j].st_info)==STT_OBJECT || 1244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ELF_ST_TYPE(stab[j].st_info)==STT_NOTYPE 1245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ) 1246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ) { 1247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Section 0 is the undefined section, hence > and not >=. */ 1248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(secno > 0 && secno < ehdr->e_shnum); 1249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* 1250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (shdr[secno].sh_type == SHT_NOBITS) { 1251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, " BSS symbol, size %d off %d name %s\n", 1252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov stab[j].st_size, stab[j].st_value, nm); 1253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 1255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ad = ehdrC + shdr[ secno ].sh_offset + stab[j].st_value; 1256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ELF_ST_BIND(stab[j].st_info)==STB_LOCAL) { 1257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov isLocal = TRUE; 1258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 1259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef ELF_FUNCTION_DESC 1260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* dlsym() and the initialisation table both give us function 1261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * descriptors, so to be consistent we store function descriptors 1262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * in the symbol table */ 1263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ELF_ST_TYPE(stab[j].st_info) == STT_FUNC) 1264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ad = (char *)allocateFunctionDesc((Elf_Addr)ad); 1265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0|| debug_linker) 1267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "addOTabName(GLOB): %10p %s %s\n", 1268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ad, oc->fileName, nm ); 1269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov isLocal = FALSE; 1270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* And the decision is ... */ 1274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ad != NULL) { 1276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(nm != NULL); 1277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->symbols[j] = nm; 1278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Acquire! */ 1279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (isLocal) { 1280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Ignore entirely. */ 1281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 1282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //ghciInsertStrHashTable(oc->fileName, global_symbol_table, nm, ad); 1283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov paranoid_addto_StringMap(global_symbol_table, nm, ad); 1284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 1286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Skip. */ 1287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (debug_linker>1) fprintf(stderr, "skipping `%s'\n", 1288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov strtab + stab[j].st_name ); 1289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* 1290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, 1291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "skipping bind = %d, type = %d, shndx = %d `%s'\n", 1292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (int)ELF_ST_BIND(stab[j].st_info), 1293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (int)ELF_ST_TYPE(stab[j].st_info), 1294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (int)stab[j].st_shndx, 1295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov strtab + stab[j].st_name 1296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); 1297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 1298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->symbols[j] = NULL; 1299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 1; 1305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 1309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 1310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/////////////////////////////////////////////////////////////////// 1311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 1312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// TOP-LEVEL CONTROL OF THE LINKER 1313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --------------------------------------------------------------------- 1316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Load an obj (populate the global symbol table, but don't resolve yet) 1317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * 1318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Returns: 1 if ok, 0 on error. 1319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 1320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 1321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint loadObj( char *path ) 1322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ObjectCode* oc; 1324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct stat st; 1325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int r; 1326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int fd, pagesize; 1327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* p; 1328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov initLinker(); 1330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "==== loadObj %s ====\n", path ); 1332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Check that we haven't already loaded this object. */ 1334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 1335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ObjectCode *o; 1336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int is_dup = 0; 1337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (o = global_object_list; o; o = o->next) { 1338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0 == strcmp(o->fileName, path)) 1339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov is_dup = 1; 1340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_dup) { 1342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, 1343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "\n\n" 1344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "GHCi runtime linker: warning: looks like you're trying to load the\n" 1345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "same object file twice:\n" 1346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov " %s\n" 1347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov , path); 1348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 1349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc = mymalloc(sizeof(ObjectCode)); 1353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->formatName = "ELF"; 1355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = stat(path, &st); 1357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (r == -1) { return 0; } 1358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* sigh, strdup() isn't a POSIX function, so do it the long way */ 1360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fileName = mymalloc( strlen(path)+1 ); 1361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov strcpy(oc->fileName, path); 1362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fileSize = st.st_size; 1364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->symbols = NULL; 1365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->sections = NULL; 1366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->lochash = new_StringMap(); 1367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->proddables = NULL; 1368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fixup = NULL; 1369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fixup_used = 0; 1370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fixup_size = 0; 1371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* chain it onto the list of objects */ 1373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->next = global_object_list; 1374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov global_object_list = oc; 1375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fd = open(path, O_RDONLY); 1377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (fd == -1) { 1378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"loadObj: can't open `%s'\n", path); 1379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 1380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Allocate a 1-page area just prior to the image, so we can put 1383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fixup code fragments there. Used for doing R_ARM_PC24 1384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov relocations for jump distances > 64M. */ 1385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pagesize = getpagesize(); 1387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // p = memalign(pagesize, N_FIXUP_PAGES * pagesize 1388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // + oc->fileSize); 1389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = mymalloc(N_FIXUP_PAGES * pagesize + oc->fileSize); 1390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) fprintf(stderr,"XXXX p = %p\n", p); 1391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (p == NULL) { 1392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"loadObj: failed to allocate space for `%s'\n", path); 1393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 1394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fixup = p; 1397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fixup_size = N_FIXUP_PAGES * pagesize; 1398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fixup_used = 0; 1399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->image = &(p[ oc->fixup_size ]); 1400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = read(fd, oc->image, oc->fileSize); 1402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (r != oc->fileSize) { 1403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr,"loadObj: failed to read `%s'\n", path); 1404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 1405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stderr, "loaded %s at %p (fixup = %p)\n", 1408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->fileName, oc->image, oc->fixup ); 1409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov close(fd); 1411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* verify the in-memory image */ 1413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = ocVerifyImage_ELF ( oc ); 1414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!r) { return r; } 1415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* build the symbol list for this image */ 1417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = ocGetNames_ELF ( oc ); 1418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!r) { return r; } 1419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* loaded, but not resolved yet */ 1421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->status = OBJECT_LOADED; 1422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef ppc32_TARGET_ARCH 1424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache(oc->image, oc->fileSize); 1425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 1; 1428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --------------------------------------------------------------------------- 1433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * resolve all the currently unlinked objects in memory 1434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * 1435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Returns: 1 if ok, 0 on error. 1436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 1437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 1438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint resolveObjs( void ) 1439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ObjectCode *oc; 1441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int r; 1442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov initLinker(); 1444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (oc = global_object_list; oc; oc = oc->next) { 1446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (oc->status != OBJECT_RESOLVED) { 1447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = ocResolve_ELF ( oc ); 1448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!r) { return r; } 1449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oc->status = OBJECT_RESOLVED; 1450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 1; 1453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --------------------------------------------------------------------------- 1457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Top-level linker. 1458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 1459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Load and link a bunch of .o's, and return the address of 1461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 'entry'. Or NULL if something borks. 1462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 1463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid* linker_top_level_LINK ( int n_object_names, char** object_names ) 1464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int r, i; 1466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* mainp; 1467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov initLinker(); 1469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < n_object_names; i++) { 1470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //fprintf(stderr, "linkloop %d %s\n", i, object_names[i] ); 1471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = loadObj( object_names[i] ); 1472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (r != 1) return NULL; 1473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = resolveObjs(); 1475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (r != 1) return NULL; 1476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mainp = search_StringMap ( global_symbol_table, "entry" ); 1477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (mainp == NULL) return NULL; 1478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("switchback: Linker: success!\n"); 1479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return mainp; 1480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1484