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