github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-elf-read.c (about)

     1  /*
     2   * jit-elf-read.c - Routines to read ELF-format binaries.
     3   *
     4   * Copyright (C) 2004  Southern Storm Software, Pty Ltd.
     5   *
     6   * This file is part of the libjit library.
     7   *
     8   * The libjit library is free software: you can redistribute it and/or
     9   * modify it under the terms of the GNU Lesser General Public License
    10   * as published by the Free Software Foundation, either version 2.1 of
    11   * the License, or (at your option) any later version.
    12   *
    13   * The libjit library is distributed in the hope that it will be useful,
    14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    16   * Lesser General Public License for more details.
    17   *
    18   * You should have received a copy of the GNU Lesser General Public
    19   * License along with the libjit library.  If not, see
    20   * <http://www.gnu.org/licenses/>.
    21   */
    22  
    23  #include "jit-internal.h"
    24  #include "jit-rules.h"
    25  #include "jit-elf-defs.h"
    26  #ifdef JIT_WIN32_PLATFORM
    27  	#ifdef HAVE_SYS_TYPES_H
    28  		#include <sys/types.h>
    29  	#endif
    30  	#include <windows.h>
    31  	#include <io.h>
    32  	#include <fcntl.h>
    33  #else
    34  #ifdef HAVE_SYS_TYPES_H
    35  	#include <sys/types.h>
    36  #endif
    37  #ifdef HAVE_SYS_STAT_H
    38  	#include <sys/stat.h>
    39  #endif
    40  #ifdef HAVE_FCNTL_H
    41  	#include <fcntl.h>
    42  #endif
    43  #ifdef HAVE_UNISTD_H
    44  	#include <unistd.h>
    45  #endif
    46  #ifdef HAVE_SYS_MMAN_H
    47  	#include <sys/mman.h>
    48  	#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(HAVE_MPROTECT)
    49  		#define	JIT_USE_MMAP_TO_LOAD 1
    50  		#ifndef	MAP_ANON
    51  			#ifdef MAP_ANONYMOUS
    52  				#define	MAP_ANON	MAP_ANONYMOUS
    53  			#else
    54  				#define	MAP_ANON	0
    55  			#endif
    56  		#endif
    57  		#ifndef MAP_FIXED
    58  			#define	MAP_FIXED		0
    59  		#endif
    60  		#ifndef MAP_COPY
    61  			#define	MAP_COPY		MAP_PRIVATE
    62  		#endif
    63  	#endif
    64  #endif
    65  #endif
    66  #include <stdio.h>
    67  
    68  /*@
    69  
    70  The @code{libjit} library contains routines that permit pre-compiling
    71  JIT'ed functions into an on-disk representation.  This representation
    72  can be loaded at some future time, to avoid the overhead of compiling
    73  the functions at runtime.
    74  
    75  We use the ELF format for this purpose, which is a common binary format
    76  used by modern operating systems and compilers.
    77  
    78  It isn't necessary for your operating system to be based on ELF natively.
    79  We use our own routines to read and write ELF binaries.  We chose ELF
    80  because it has all of the features that we require, and reusing an
    81  existing format was better than inventing a completely new one.
    82  
    83  @section Reading ELF binaries
    84  
    85  @*/
    86  
    87  /*
    88   * Determine whether we should be using the 32-bit or 64-bit ELF structures.
    89   */
    90  #ifdef JIT_NATIVE_INT32
    91  	typedef Elf32_Ehdr  Elf_Ehdr;
    92  	typedef Elf32_Shdr  Elf_Shdr;
    93  	typedef Elf32_Phdr  Elf_Phdr;
    94  	typedef Elf32_Addr  Elf_Addr;
    95  	typedef Elf32_Word  Elf_Word;
    96  	typedef Elf32_Xword Elf_Xword;
    97  	typedef Elf32_Off   Elf_Off;
    98  	typedef Elf32_Dyn   Elf_Dyn;
    99  	typedef Elf32_Sym   Elf_Sym;
   100  	typedef Elf32_Rel   Elf_Rel;
   101  	typedef Elf32_Rela  Elf_Rela;
   102  	#define ELF_R_SYM(val)	ELF32_R_SYM((val))
   103  	#define ELF_R_TYPE(val)	ELF32_R_TYPE((val))
   104  #else
   105  	typedef Elf64_Ehdr  Elf_Ehdr;
   106  	typedef Elf64_Shdr  Elf_Shdr;
   107  	typedef Elf64_Phdr  Elf_Phdr;
   108  	typedef Elf64_Addr  Elf_Addr;
   109  	typedef Elf64_Word  Elf_Word;
   110  	typedef Elf64_Xword Elf_Xword;
   111  	typedef Elf64_Off   Elf_Off;
   112  	typedef Elf64_Dyn   Elf_Dyn;
   113  	typedef Elf64_Sym   Elf_Sym;
   114  	typedef Elf64_Rel   Elf_Rel;
   115  	typedef Elf64_Rela  Elf_Rela;
   116  	#define ELF_R_SYM(val)	ELF64_R_SYM((val))
   117  	#define ELF_R_TYPE(val)	ELF64_R_TYPE((val))
   118  #endif
   119  
   120  /*
   121   * Deal with platform differences in the file descriptor routines.
   122   */
   123  #ifdef JIT_WIN32_PLATFORM
   124  	#define sys_open		_open
   125  	#define	sys_close		_close
   126  	#define	sys_read		_read
   127  	#define	sys_lseek		_lseek
   128  #else
   129  	#define sys_open		open
   130  	#define	sys_close		close
   131  	#define	sys_read		read
   132  	#define	sys_lseek		lseek
   133  #endif
   134  #ifndef O_BINARY
   135  	#define	O_BINARY		0
   136  #endif
   137  
   138  /*
   139   * Define the relocation function type.
   140   */
   141  typedef int (*jit_reloc_func)(jit_readelf_t readelf, void *address,
   142  							  int type, jit_nuint value, int has_addend,
   143  							  jit_nuint addend);
   144  
   145  /*
   146   * Get the relocation function for a particular machine type.
   147   */
   148  static jit_reloc_func get_reloc(unsigned int machine);
   149  
   150  /*
   151   * Structure of an ELF binary once it has been loaded into memory.
   152   */
   153  struct jit_readelf
   154  {
   155  	jit_readelf_t	next;
   156  	int				resolved;
   157  	Elf_Ehdr		ehdr;
   158  	unsigned char  *phdrs;
   159  	unsigned char  *shdrs;
   160  	char		   *regular_strings;
   161  	jit_nuint		regular_strings_size;
   162  	char		   *dynamic_strings;
   163  	jit_nuint		dynamic_strings_size;
   164  	Elf_Sym		   *symbol_table;
   165  	jit_nuint		symbol_table_size;
   166  	Elf_Word	   *symbol_hash;
   167  	jit_nuint		symbol_hash_size;
   168  	Elf_Word		symbol_hash_buckets;
   169  	jit_reloc_func	reloc_func;
   170  	void		   *map_address;
   171  	jit_nuint		map_size;
   172  	int				free_with_munmap;
   173  };
   174  
   175  /*
   176   * Flag that indicates that an auxillary section was malloc'ed,
   177   * and isn't part of the main memory range at "map_address".
   178   */
   179  #define	JIT_ELF_IS_MALLOCED			0x01000000
   180  
   181  /*
   182   * Get the address of a particular phdr.
   183   */
   184  static Elf_Phdr *get_phdr(jit_readelf_t readelf, unsigned int index)
   185  {
   186  	if(index < readelf->ehdr.e_phnum &&
   187  	   readelf->ehdr.e_phentsize >= sizeof(Elf_Phdr))
   188  	{
   189  		return (Elf_Phdr *)
   190  			(readelf->phdrs +
   191  			 index * ((unsigned int)(readelf->ehdr.e_phentsize)));
   192  	}
   193  	else
   194  	{
   195  		return 0;
   196  	}
   197  }
   198  
   199  /*
   200   * Get the address of a particular shdr.
   201   */
   202  static Elf_Shdr *get_shdr(jit_readelf_t readelf, unsigned int index)
   203  {
   204  	if(index < readelf->ehdr.e_shnum &&
   205  	   readelf->ehdr.e_shentsize >= sizeof(Elf_Shdr))
   206  	{
   207  		return (Elf_Shdr *)
   208  			(readelf->shdrs +
   209  			 index * ((unsigned int)(readelf->ehdr.e_shentsize)));
   210  	}
   211  	else
   212  	{
   213  		return 0;
   214  	}
   215  }
   216  
   217  /*
   218   * Find a specific string in the regular string table.
   219   */
   220  static const char *get_string(jit_readelf_t readelf, Elf_Word _index)
   221  {
   222  	jit_nuint index = (jit_nuint)_index;
   223  	if(index < readelf->regular_strings_size)
   224  	{
   225  		return readelf->regular_strings + index;
   226  	}
   227  	else
   228  	{
   229  		return 0;
   230  	}
   231  }
   232  
   233  /*
   234   * Find a specific string in the dynamic string table.
   235   */
   236  static const char *get_dyn_string(jit_readelf_t readelf, Elf_Addr _index)
   237  {
   238  	jit_nuint index = (jit_nuint)_index;
   239  	if(index < readelf->dynamic_strings_size)
   240  	{
   241  		return readelf->dynamic_strings + index;
   242  	}
   243  	else
   244  	{
   245  		return 0;
   246  	}
   247  }
   248  
   249  /*
   250   * Map all of the program segments into memory and set up the bss section.
   251   */
   252  static int map_program(jit_readelf_t readelf, int fd)
   253  {
   254  	Elf_Off file_size;
   255  	Elf_Off memory_size;
   256  	Elf_Off start, end;
   257  	Elf_Phdr *phdr;
   258  	unsigned int index;
   259  	void *base_address;
   260  	unsigned char *segment_address;
   261  
   262  	/* Get the maximum file and memory sizes for the program.
   263  	   The bytes between "file_size" and "memory_size" are bss */
   264  	file_size = 0;
   265  	memory_size = 0;
   266  	for(index = 0; index < readelf->ehdr.e_phnum; ++index)
   267  	{
   268  		phdr = get_phdr(readelf, index);
   269  		if(!phdr)
   270  		{
   271  			continue;
   272  		}
   273  		start = phdr->p_offset;
   274  		end = start + phdr->p_filesz;
   275  		if(end > file_size)
   276  		{
   277  			file_size = end;
   278  		}
   279  		start = phdr->p_vaddr;
   280  		end = start + phdr->p_memsz;
   281  		if(end > memory_size)
   282  		{
   283  			memory_size = end;
   284  		}
   285  	}
   286  	if(memory_size < file_size)
   287  	{
   288  		memory_size = file_size;
   289  	}
   290  
   291  	/* Try to map the program segments into memory using mmap */
   292  	base_address = 0;
   293  #ifdef JIT_USE_MMAP_TO_LOAD
   294  	{
   295  		Elf_Off page_size;
   296  		Elf_Off rounded_file_size;
   297  		Elf_Off temp_start;
   298  		Elf_Off temp_end;
   299  		int zero_fd, prot;
   300  
   301  		/* Round the total memory and file sizes up to the CPU page size */
   302  		page_size = (Elf_Off)(jit_vmem_page_size());
   303  		end = memory_size;
   304  		if((end % page_size) != 0)
   305  		{
   306  			end += page_size - (end % page_size);
   307  		}
   308  		rounded_file_size = file_size;
   309  		if((rounded_file_size % page_size) != 0)
   310  		{
   311  			rounded_file_size += page_size - (rounded_file_size % page_size);
   312  		}
   313  
   314  		/* Allocate memory for the program from /dev/zero.  Once we have
   315  		   the memory, we will overlay the program segments on top */
   316  		zero_fd = sys_open("/dev/zero", O_RDWR, 0);
   317  		if(zero_fd < -1)
   318  		{
   319  			goto failed_mmap;
   320  		}
   321  		base_address = mmap(0, (size_t)end, PROT_READ | PROT_WRITE,
   322  							MAP_ANON | MAP_PRIVATE, zero_fd, 0);
   323  		close(zero_fd);
   324  		if(base_address == (void *)(jit_nint)(-1))
   325  		{
   326  			base_address = 0;
   327  			goto failed_mmap;
   328  		}
   329  
   330  		/* Lay down the program sections at their mapped locations */
   331  		for(index = 0; index < readelf->ehdr.e_phnum; ++index)
   332  		{
   333  			phdr = get_phdr(readelf, index);
   334  			if(phdr)
   335  			{
   336  				temp_start = phdr->p_offset;
   337  				temp_end = temp_start + phdr->p_filesz;
   338  				temp_start -= (temp_start % page_size);
   339  				if((temp_end % page_size) != 0)
   340  				{
   341  					temp_end += page_size - (temp_end % page_size);
   342  				}
   343  				start = phdr->p_vaddr;
   344  				start -= (start % page_size);
   345  				if(temp_start < temp_end)
   346  				{
   347  					segment_address =
   348  						((unsigned char *)base_address) + (jit_nuint)start;
   349  					prot = 0;
   350  					if((phdr->p_flags & PF_X) != 0)
   351  					{
   352  						prot |= PROT_EXEC;
   353  					}
   354  					if((phdr->p_flags & PF_W) != 0)
   355  					{
   356  						prot |= PROT_WRITE;
   357  					}
   358  					if((phdr->p_flags & PF_R) != 0)
   359  					{
   360  						prot |= PROT_READ;
   361  					}
   362  					if(mmap(segment_address, (size_t)(temp_end - temp_start),
   363  						    prot, MAP_COPY | MAP_FILE | MAP_FIXED, fd,
   364  							(off_t)temp_start) == (void *)(jit_nint)(-1))
   365  					{
   366  						munmap(base_address, (size_t)end);
   367  						base_address = 0;
   368  						goto failed_mmap;
   369  					}
   370  				}
   371  			}
   372  		}
   373  
   374  		/* We need to free the memory with munmap when the program is closed */
   375  		readelf->free_with_munmap = 1;
   376  
   377  		/* Clear the left-over ".bss" bits that did not get cleared above */
   378  		for(index = 0; index < readelf->ehdr.e_phnum; ++index)
   379  		{
   380  			phdr = get_phdr(readelf, index);
   381  			if(phdr && phdr->p_filesz < phdr->p_memsz)
   382  			{
   383  				temp_start = phdr->p_vaddr + phdr->p_filesz;
   384  				start = (temp_start % page_size);
   385  				temp_start -= start;
   386  				if(start != 0)
   387  				{
   388  					segment_address =
   389  						((unsigned char *)base_address) +
   390  						(jit_nuint)temp_start;
   391  					mprotect(segment_address, (size_t)page_size,
   392  							 PROT_READ | PROT_WRITE);
   393  					jit_memzero(segment_address + (jit_nuint)start,
   394  							    (unsigned int)(page_size - start));
   395  					prot = 0;
   396  					if((phdr->p_flags & PF_X) != 0)
   397  					{
   398  						prot |= PROT_EXEC;
   399  					}
   400  					if((phdr->p_flags & PF_W) != 0)
   401  					{
   402  						prot |= PROT_WRITE;
   403  					}
   404  					if((phdr->p_flags & PF_R) != 0)
   405  					{
   406  						prot |= PROT_READ;
   407  					}
   408  					mprotect(segment_address, (size_t)page_size, prot);
   409  				}
   410  			}
   411  		}
   412  	}
   413  failed_mmap:
   414  #endif /* JIT_USE_MMAP_TO_LOAD */
   415  
   416  	/* If we haven't mapped the file yet, then fall back to "malloc" */
   417  	if(!base_address)
   418  	{
   419  		base_address = _jit_malloc_exec(memory_size);
   420  		if(!base_address)
   421  		{
   422  			return 0;
   423  		}
   424  		for(index = 0; index < readelf->ehdr.e_phnum; ++index)
   425  		{
   426  			phdr = get_phdr(readelf, index);
   427  			if(phdr)
   428  			{
   429  				segment_address = ((unsigned char *)base_address) +
   430  								  (jit_nuint)(phdr->p_vaddr);
   431  				if(lseek(fd, (off_t)(phdr->p_offset), 0) !=
   432  						(off_t)(phdr->p_offset) ||
   433  	               read(fd, segment_address, (size_t)(phdr->p_filesz))
   434  				   		!= (int)(size_t)(phdr->p_filesz))
   435  				{
   436  					_jit_free_exec(base_address, memory_size);
   437  					return 0;
   438  				}
   439  			}
   440  		}
   441  	}
   442  
   443  	/* Record the mapped address and size for later */
   444  	readelf->map_address = base_address;
   445  	readelf->map_size = memory_size;
   446  	return 1;
   447  }
   448  
   449  /*
   450   * Map an auxillary section into memory and return its base address.
   451   * Returns NULL if we ran out of memory.
   452   */
   453  static void *map_section(int fd, Elf_Off offset, Elf_Xword file_size,
   454  						 Elf_Xword memory_size, Elf_Word flags)
   455  {
   456  	void *address;
   457  	if(memory_size < file_size)
   458  	{
   459  		memory_size = file_size;
   460  	}
   461  	address = _jit_malloc_exec(memory_size);
   462  	if(!address)
   463  	{
   464  		return 0;
   465  	}
   466  	if(lseek(fd, (off_t)offset, 0) != (off_t)offset)
   467  	{
   468  		_jit_free_exec(address, memory_size);
   469  		return 0;
   470  	}
   471  	if(read(fd, address, (size_t)file_size) != (int)(size_t)file_size)
   472  	{
   473  		_jit_free_exec(address, memory_size);
   474  		return 0;
   475  	}
   476  	return address;
   477  }
   478  
   479  /*
   480   * Unmap an auxillary section from memory.
   481   */
   482  static void unmap_section(void *address, Elf_Xword file_size,
   483  						  Elf_Xword memory_size, Elf_Word flags)
   484  {
   485  	if(memory_size < file_size)
   486  	{
   487  		memory_size = file_size;
   488  	}
   489  	if((flags & JIT_ELF_IS_MALLOCED) != 0)
   490  	{
   491  		_jit_free_exec(address, (unsigned int)memory_size);
   492  	}
   493  }
   494  
   495  /*
   496   * Iterate over the contents of the ".dynamic" section.
   497   */
   498  typedef struct
   499  {
   500  	Elf_Dyn    *dyn;
   501  	jit_nuint	size;
   502  
   503  } jit_dynamic_iter_t;
   504  static void dynamic_iter_init(jit_dynamic_iter_t *iter, jit_readelf_t readelf)
   505  {
   506  	iter->dyn = jit_readelf_get_section_by_type
   507  		(readelf, SHT_DYNAMIC, &(iter->size));
   508  }
   509  static int dynamic_iter_next
   510  	(jit_dynamic_iter_t *iter, jit_uint *type, Elf_Addr *value)
   511  {
   512  	if(iter->size >= sizeof(Elf_Dyn))
   513  	{
   514  		*type = (jit_uint)(iter->dyn->d_tag);
   515  		*value = iter->dyn->d_un.d_ptr;
   516  		if(*type == DT_NULL)
   517  		{
   518  			/* Explicitly-marked end of the list */
   519  			return 0;
   520  		}
   521  		++(iter->dyn);
   522  		iter->size -= sizeof(Elf_Dyn);
   523  		return 1;
   524  	}
   525  	else
   526  	{
   527  		/* Implicitly-marked end of the list */
   528  		return 0;
   529  	}
   530  }
   531  static int dynamic_for_type
   532  	(jit_readelf_t readelf, jit_uint type, Elf_Addr *value)
   533  {
   534  	Elf_Addr temp_value;
   535  	jit_dynamic_iter_t iter;
   536  	jit_uint iter_type;
   537  	dynamic_iter_init(&iter, readelf);
   538  	while(dynamic_iter_next(&iter, &iter_type, &temp_value))
   539  	{
   540  		if(iter_type == type)
   541  		{
   542  			if(value)
   543  			{
   544  				*value = temp_value;
   545  			}
   546  			return 1;
   547  		}
   548  	}
   549  	return 0;
   550  }
   551  
   552  /*
   553   * Load interesting values from the ".dynamic" section, for quicker lookups.
   554   */
   555  static void load_dynamic_section(jit_readelf_t readelf, int flags)
   556  {
   557  	Elf_Addr value;
   558  	Elf_Addr value2;
   559  	jit_dynamic_iter_t iter;
   560  	jit_uint type;
   561  	jit_nuint size;
   562  
   563  	/* Get the position and size of the dynamic string table */
   564  	if(dynamic_for_type(readelf, DT_STRTAB, &value) &&
   565  	   dynamic_for_type(readelf, DT_STRSZ, &value2))
   566  	{
   567  		readelf->dynamic_strings = jit_readelf_map_vaddr
   568  			(readelf, (jit_nuint)value);
   569  		if(readelf->dynamic_strings)
   570  		{
   571  			readelf->dynamic_strings_size = (jit_nuint)value2;
   572  		}
   573  	}
   574  
   575  	/* Get the position and size of the dynamic symbol table */
   576  	readelf->symbol_table = jit_readelf_get_section_by_type
   577  		(readelf, SHT_DYNSYM, &size);
   578  	if(readelf->symbol_table)
   579  	{
   580  		if(dynamic_for_type(readelf, DT_SYMENT, &value) &&
   581  		   value == sizeof(Elf_Sym))
   582  		{
   583  			readelf->symbol_table_size = size / sizeof(Elf_Sym);
   584  			readelf->symbol_hash = jit_readelf_get_section_by_type
   585  				(readelf, SHT_HASH, &size);
   586  			if(readelf->symbol_hash)
   587  			{
   588  				readelf->symbol_hash_size = size / sizeof(Elf_Word);
   589  				if(readelf->symbol_hash_size >= 2)
   590  				{
   591  					readelf->symbol_hash_buckets = readelf->symbol_hash[0];
   592  				}
   593  			}
   594  		}
   595  		else
   596  		{
   597  			readelf->symbol_table = 0;
   598  		}
   599  	}
   600  
   601  	/* Bail out if we don't need to print debugging information */
   602  	if((flags & JIT_READELF_FLAG_DEBUG) == 0)
   603  	{
   604  		return;
   605  	}
   606  
   607  	/* Iterate through the ".dynamic" section, dumping all that we find */
   608  	dynamic_iter_init(&iter, readelf);
   609  	while(dynamic_iter_next(&iter, &type, &value))
   610  	{
   611  		switch(type)
   612  		{
   613  			case DT_NEEDED:
   614  			{
   615  				printf("needed library: %s\n", get_dyn_string(readelf, value));
   616  			}
   617  			break;
   618  
   619  			case DT_PLTRELSZ:
   620  			{
   621  				printf("total size of PLT relocs: %ld\n", (long)value);
   622  			}
   623  			break;
   624  
   625  			case DT_PLTGOT:
   626  			{
   627  				printf("address of PLTGOT table: 0x%lx\n", (long)value);
   628  			}
   629  			break;
   630  
   631  			case DT_HASH:
   632  			{
   633  				printf("address of symbol hash table: 0x%lx\n", (long)value);
   634  			}
   635  			break;
   636  
   637  			case DT_STRTAB:
   638  			{
   639  				printf("address of string table: 0x%lx\n", (long)value);
   640  			}
   641  			break;
   642  
   643  			case DT_SYMTAB:
   644  			{
   645  				printf("address of symbol table: 0x%lx\n", (long)value);
   646  			}
   647  			break;
   648  
   649  			case DT_STRSZ:
   650  			{
   651  				printf("size of string table: %ld\n", (long)value);
   652  			}
   653  			break;
   654  
   655  			case DT_SYMENT:
   656  			{
   657  				printf("size of one symbol table entry: %ld\n", (long)value);
   658  			}
   659  			break;
   660  
   661  			case DT_INIT:
   662  			{
   663  				printf("address of init function: 0x%lx\n", (long)value);
   664  			}
   665  			break;
   666  
   667  			case DT_FINI:
   668  			{
   669  				printf("address of fini function: 0x%lx\n", (long)value);
   670  			}
   671  			break;
   672  
   673  			case DT_SONAME:
   674  			{
   675  				printf("library name: %s\n", get_dyn_string(readelf, value));
   676  			}
   677  			break;
   678  
   679  			case DT_REL:
   680  			{
   681  				printf("address of Rel relocs: 0x%lx\n", (long)value);
   682  			}
   683  			break;
   684  
   685  			case DT_RELSZ:
   686  			{
   687  				printf("total size of Rel relocs: %ld\n", (long)value);
   688  			}
   689  			break;
   690  
   691  			case DT_RELENT:
   692  			{
   693  				printf("size of one Rel reloc: %ld\n", (long)value);
   694  			}
   695  			break;
   696  
   697  			case DT_RELA:
   698  			{
   699  				printf("address of Rela relocs: 0x%lx\n", (long)value);
   700  			}
   701  			break;
   702  
   703  			case DT_RELASZ:
   704  			{
   705  				printf("total size of Rela relocs: %ld\n", (long)value);
   706  			}
   707  			break;
   708  
   709  			case DT_RELAENT:
   710  			{
   711  				printf("size of one Rela reloc: %ld\n", (long)value);
   712  			}
   713  			break;
   714  
   715  			case DT_PLTREL:
   716  			{
   717  				printf("type of PLT relocs: %ld\n", (long)value);
   718  			}
   719  			break;
   720  
   721  			case DT_JMPREL:
   722  			{
   723  				printf("address of PLT relocs: 0x%lx\n", (long)value);
   724  			}
   725  			break;
   726  
   727  			default:
   728  			{
   729  				printf("dynamic info of type 0x%x: 0x%lx\n",
   730  					   (int)type, (long)value);
   731  			}
   732  			break;
   733  		}
   734  	}
   735  
   736  	/* Iterate through the symbol table, dumping all of the entries */
   737  	for(size = 0; size < readelf->symbol_table_size; ++size)
   738  	{
   739  		printf("%08lX %02X%02X %2d %s\n",
   740  			   (long)(readelf->symbol_table[size].st_value),
   741  			   (int)(readelf->symbol_table[size].st_info),
   742  			   (int)(readelf->symbol_table[size].st_other),
   743  			   (int)(readelf->symbol_table[size].st_shndx),
   744  			   get_dyn_string(readelf, readelf->symbol_table[size].st_name));
   745  	}
   746  	printf("number of symbols: %ld\n", (long)(readelf->symbol_table_size));
   747  	printf("number of symbol hash entries: %ld\n",
   748  		   (long)(readelf->symbol_hash_size));
   749  }
   750  
   751  /*@
   752   * @deftypefun int jit_readelf_open (jit_readelf_t *@var{readelf}, const char *@var{filename}, int @var{force})
   753   * Open the specified @var{filename} and load the ELF binary that is
   754   * contained within it.  Returns one of the following result codes:
   755   *
   756   * @table @code
   757   * @vindex JIT_READELF_OK
   758   * @item JIT_READELF_OK
   759   * The ELF binary was opened successfully.
   760   *
   761   * @vindex JIT_READELF_CANNOT_OPEN
   762   * @item JIT_READELF_CANNOT_OPEN
   763   * Could not open the file at the filesystem level (reason in @code{errno}).
   764   *
   765   * @vindex JIT_READELF_NOT_ELF
   766   * @item JIT_READELF_NOT_ELF
   767   * The file was opened, but it is not an ELF binary.
   768   *
   769   * @vindex JIT_READELF_WRONG_ARCH
   770   * @item JIT_READELF_WRONG_ARCH
   771   * The file is an ELF binary, but it does not pertain to the architecture
   772   * of this machine.
   773   *
   774   * @vindex JIT_READELF_BAD_FORMAT
   775   * @item JIT_READELF_BAD_FORMAT
   776   * The file is an ELF binary, but the format is corrupted in some fashion.
   777   *
   778   * @vindex JIT_READELF_MEMORY
   779   * @item JIT_READELF_MEMORY
   780   * There is insufficient memory to open the ELF binary.
   781   * @end table
   782   *
   783   * The following flags may be supplied to alter the manner in which
   784   * the ELF binary is loaded:
   785   *
   786   * @table @code
   787   * @vindex JIT_READELF_FLAG_FORCE
   788   * @item JIT_READELF_FLAG_FORCE
   789   * Force @code{jit_readelf_open} to open the ELF binary, even if
   790   * the architecture does not match this machine.  Useful for debugging.
   791   *
   792   * @vindex JIT_READELF_FLAG_DEBUG
   793   * @item JIT_READELF_FLAG_DEBUG
   794   * Print additional debug information to stdout.
   795   * @end table
   796   * @end deftypefun
   797  @*/
   798  int jit_readelf_open(jit_readelf_t *_readelf, const char *filename, int flags)
   799  {
   800  	int fd;
   801  	Elf_Ehdr ehdr;
   802  	Elf_Phdr *phdr;
   803  	Elf_Shdr *shdr;
   804  	jit_elf_info_t elf_info;
   805  	jit_readelf_t readelf;
   806  	unsigned int phdr_size;
   807  	unsigned int shdr_size;
   808  	unsigned int index;
   809  	void *address;
   810  	union
   811  	{
   812  		jit_ushort value;
   813  		unsigned char bytes[2];
   814  
   815  	} un;
   816  
   817  	/* Get the machine and ABI values that we expect in the header */
   818  	_jit_gen_get_elf_info(&elf_info);
   819  
   820  	/* Open the file and read the ELF magic number information */
   821  	if((fd = sys_open(filename, O_RDONLY | O_BINARY, 0)) < 0)
   822  	{
   823  		return JIT_READELF_CANNOT_OPEN;
   824  	}
   825  	if(sys_read(fd, ehdr.e_ident, EI_NIDENT) != EI_NIDENT)
   826  	{
   827  		sys_close(fd);
   828  		return JIT_READELF_NOT_ELF;
   829  	}
   830  
   831  	/* Determine if the magic number matches what we expect to see */
   832  	if(ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
   833  	   ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3)
   834  	{
   835  		sys_close(fd);
   836  		return JIT_READELF_NOT_ELF;
   837  	}
   838  #ifdef JIT_NATIVE_INT32
   839  	if(ehdr.e_ident[EI_CLASS] != ELFCLASS32)
   840  	{
   841  		sys_close(fd);
   842  		return JIT_READELF_WRONG_ARCH;
   843  	}
   844  #else
   845  	if(ehdr.e_ident[EI_CLASS] != ELFCLASS64)
   846  	{
   847  		sys_close(fd);
   848  		return JIT_READELF_WRONG_ARCH;
   849  	}
   850  #endif
   851  	un.value = 0x0102;
   852  	if(un.bytes[0] == 0x01)
   853  	{
   854  		/* Looking for a big-endian binary */
   855  		if(ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
   856  		{
   857  			sys_close(fd);
   858  			return JIT_READELF_WRONG_ARCH;
   859  		}
   860  	}
   861  	else
   862  	{
   863  		/* Looking for a little-endian binary */
   864  		if(ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
   865  		{
   866  			sys_close(fd);
   867  			return JIT_READELF_WRONG_ARCH;
   868  		}
   869  	}
   870  	if(ehdr.e_ident[EI_VERSION] != EV_CURRENT)
   871  	{
   872  		sys_close(fd);
   873  		return JIT_READELF_BAD_FORMAT;
   874  	}
   875  
   876  	/* Read the rest of the ELF header and validate it */
   877  	if(sys_read(fd, &(ehdr.e_type), sizeof(Elf_Ehdr) - EI_NIDENT)
   878  			!= (sizeof(Elf_Ehdr) - EI_NIDENT))
   879  	{
   880  		sys_close(fd);
   881  		return JIT_READELF_BAD_FORMAT;
   882  	}
   883  	if(ehdr.e_type != ET_DYN)
   884  	{
   885  		/* We can only load files that are marked as dynamic shared objects */
   886  		sys_close(fd);
   887  		return JIT_READELF_WRONG_ARCH;
   888  	}
   889  	if((flags & JIT_READELF_FLAG_FORCE) == 0)
   890  	{
   891  		if(ehdr.e_machine != elf_info.machine ||
   892  		   ehdr.e_ident[EI_OSABI] != elf_info.abi ||
   893  		   ehdr.e_ident[EI_ABIVERSION] != elf_info.abi_version)
   894  		{
   895  			/* The ELF binary does not pertain to this machine or ABI type */
   896  			sys_close(fd);
   897  			return JIT_READELF_WRONG_ARCH;
   898  		}
   899  	}
   900  	if(ehdr.e_version != EV_CURRENT)
   901  	{
   902  		sys_close(fd);
   903  		return JIT_READELF_BAD_FORMAT;
   904  	}
   905  	if(ehdr.e_ehsize < sizeof(ehdr))
   906  	{
   907  		sys_close(fd);
   908  		return JIT_READELF_BAD_FORMAT;
   909  	}
   910  
   911  	/* Allocate space for the ELF reader object */
   912  	if((readelf = jit_cnew(struct jit_readelf)) == 0)
   913  	{
   914  		sys_close(fd);
   915  		return JIT_READELF_MEMORY;
   916  	}
   917  	readelf->ehdr = ehdr;
   918  	phdr_size = ((unsigned int)(ehdr.e_phnum)) *
   919  				((unsigned int)(ehdr.e_phentsize));
   920  	shdr_size = ((unsigned int)(ehdr.e_shnum)) *
   921  				((unsigned int)(ehdr.e_shentsize));
   922  	if(phdr_size > 0)
   923  	{
   924  		readelf->phdrs = (unsigned char *)jit_malloc(phdr_size);
   925  		if(!(readelf->phdrs))
   926  		{
   927  			jit_free(readelf);
   928  			sys_close(fd);
   929  			return JIT_READELF_MEMORY;
   930  		}
   931  	}
   932  	if(shdr_size > 0)
   933  	{
   934  		readelf->shdrs = (unsigned char *)jit_malloc(shdr_size);
   935  		if(!(readelf->shdrs))
   936  		{
   937  			jit_free(readelf->phdrs);
   938  			jit_free(readelf);
   939  			sys_close(fd);
   940  			return JIT_READELF_MEMORY;
   941  		}
   942  	}
   943  
   944  	/* Seek to the program and section header tables and read them */
   945  	if(phdr_size > 0)
   946  	{
   947  		if(lseek(fd, (off_t)(ehdr.e_phoff), 0) != (off_t)(ehdr.e_phoff) ||
   948  		   read(fd, readelf->phdrs, phdr_size) != (int)phdr_size)
   949  		{
   950  			jit_free(readelf->shdrs);
   951  			jit_free(readelf->phdrs);
   952  			jit_free(readelf);
   953  			sys_close(fd);
   954  			return JIT_READELF_BAD_FORMAT;
   955  		}
   956  	}
   957  	if(shdr_size > 0)
   958  	{
   959  		if(lseek(fd, (off_t)(ehdr.e_shoff), 0) != (off_t)(ehdr.e_shoff) ||
   960  		   read(fd, readelf->shdrs, shdr_size) != (int)shdr_size)
   961  		{
   962  			jit_free(readelf->shdrs);
   963  			jit_free(readelf->phdrs);
   964  			jit_free(readelf);
   965  			sys_close(fd);
   966  			return JIT_READELF_BAD_FORMAT;
   967  		}
   968  	}
   969  
   970  	/* Load the program segments */
   971  	if(!map_program(readelf, fd))
   972  	{
   973  		jit_readelf_close(readelf);
   974  		sys_close(fd);
   975  		return JIT_READELF_MEMORY;
   976  	}
   977  
   978  	/* Load the auxillary sections */
   979  	if(shdr_size > 0)
   980  	{
   981  		for(index = 0; index < ehdr.e_shnum; ++index)
   982  		{
   983  			shdr = get_shdr(readelf, index);
   984  			if(!shdr)
   985  			{
   986  				continue;
   987  			}
   988  			if((shdr->sh_flags & SHF_ALLOC) != 0 || shdr->sh_addr != 0)
   989  			{
   990  				/* This may be mapped inside one of the program segments.
   991  				   If so, we don't want to load a second copy of it */
   992  				address = jit_readelf_map_vaddr(readelf, shdr->sh_addr);
   993  				if(address)
   994  				{
   995  					continue;
   996  				}
   997  			}
   998  			if(shdr->sh_size == 0)
   999  			{
  1000  				/* Ignore zero-sized segments */
  1001  				continue;
  1002  			}
  1003  			address = map_section
  1004  				(fd, shdr->sh_offset, shdr->sh_size, shdr->sh_size,
  1005  				 ((shdr->sh_flags & SHF_WRITE) != 0 ? (PF_W | PF_R) : PF_R));
  1006  			if(!address)
  1007  			{
  1008  				jit_readelf_close(readelf);
  1009  				sys_close(fd);
  1010  				return JIT_READELF_MEMORY;
  1011  			}
  1012  			shdr->sh_offset = (Elf_Off)(jit_nuint)address;
  1013  			shdr->sh_flags |= JIT_ELF_IS_MALLOCED;
  1014  		}
  1015  	}
  1016  
  1017  	/* Close the file descriptor because we don't need it any more */
  1018  	sys_close(fd);
  1019  
  1020  	/* Find the regular string table */
  1021  	shdr = get_shdr(readelf, ehdr.e_shstrndx);
  1022  	if(shdr)
  1023  	{
  1024  		if((shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0)
  1025  		{
  1026  			readelf->regular_strings = (char *)(jit_nuint)(shdr->sh_offset);
  1027  		}
  1028  		else
  1029  		{
  1030  			readelf->regular_strings =
  1031  				(char *)jit_readelf_map_vaddr(readelf, shdr->sh_addr);
  1032  		}
  1033  		if(readelf->regular_strings)
  1034  		{
  1035  			readelf->regular_strings_size = (jit_nuint)(shdr->sh_size);
  1036  		}
  1037  	}
  1038  
  1039  	/* Dump debug information about the program segments and sections */
  1040  	if((flags & JIT_READELF_FLAG_DEBUG) != 0)
  1041  	{
  1042  		printf("header: machine=%d, abi=%d, abi_version=%d\n",
  1043  			   (int)(ehdr.e_machine), (int)(ehdr.e_ident[EI_OSABI]),
  1044  			   (int)(ehdr.e_ident[EI_ABIVERSION]));
  1045  		for(index = 0; index < ehdr.e_phnum; ++index)
  1046  		{
  1047  			phdr = get_phdr(readelf, index);
  1048  			if(phdr)
  1049  			{
  1050  				printf("program segment: type=%d, flags=0x%x, "
  1051  							"vaddr=0x%lx, file_size=%ld, memory_size=%ld\n",
  1052  				       (int)(phdr->p_type),
  1053  				       (int)(phdr->p_flags & ~JIT_ELF_IS_MALLOCED),
  1054  				       (long)(phdr->p_vaddr),
  1055  				       (long)(phdr->p_filesz),
  1056  				       (long)(phdr->p_memsz));
  1057  			}
  1058  		}
  1059  		for(index = 0; index < ehdr.e_shnum; ++index)
  1060  		{
  1061  			shdr = get_shdr(readelf, index);
  1062  			if(shdr)
  1063  			{
  1064  				printf("section %2d: name=\"%s\", type=%d, flags=0x%x, "
  1065  							"vaddr=0x%lx, size=%ld\n",
  1066  					   index,
  1067  				       get_string(readelf, shdr->sh_name),
  1068  				       (int)(shdr->sh_type),
  1069  				       (int)(shdr->sh_flags & ~JIT_ELF_IS_MALLOCED),
  1070  				           (long)(shdr->sh_addr),
  1071  				       (long)(shdr->sh_size));
  1072  			}
  1073  		}
  1074  	}
  1075  
  1076  	/* Get the relocation function for this machine type */
  1077  	readelf->reloc_func = get_reloc((unsigned int)(ehdr.e_machine));
  1078  
  1079  	/* Load useful values from the dynamic section that we want to cache */
  1080  	load_dynamic_section(readelf, flags);
  1081  
  1082  	/* The ELF binary is loaded and ready to go */
  1083  	*_readelf = readelf;
  1084  	return JIT_READELF_OK;
  1085  }
  1086  
  1087  /*@
  1088   * @deftypefun void jit_readelf_close (jit_readelf_t @var{readelf})
  1089   * Close an ELF reader, reclaiming all of the memory that was used.
  1090   * @end deftypefun
  1091  @*/
  1092  void jit_readelf_close(jit_readelf_t readelf)
  1093  {
  1094  	unsigned int index;
  1095  	Elf_Shdr *shdr;
  1096  	if(!readelf)
  1097  	{
  1098  		return;
  1099  	}
  1100  #ifdef JIT_USE_MMAP_TO_LOAD
  1101  	if(readelf->free_with_munmap)
  1102  	{
  1103  		munmap(readelf->map_address, (size_t)(readelf->map_size));
  1104  	}
  1105  	else
  1106  #endif
  1107  	{
  1108  		_jit_free_exec(readelf->map_address, readelf->map_size);
  1109  	}
  1110  	for(index = 0; index < readelf->ehdr.e_shnum; ++index)
  1111  	{
  1112  		shdr = get_shdr(readelf, index);
  1113  		if(shdr && (shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0)
  1114  		{
  1115  			unmap_section
  1116  				((void *)(jit_nuint)(shdr->sh_offset),
  1117  				 shdr->sh_size, shdr->sh_size, shdr->sh_flags);
  1118  		}
  1119  	}
  1120  	jit_free(readelf->phdrs);
  1121  	jit_free(readelf->shdrs);
  1122  	jit_free(readelf);
  1123  }
  1124  
  1125  /*@
  1126   * @deftypefun {const char *} jit_readelf_get_name (jit_readelf_t @var{readelf})
  1127   * Get the library name that is embedded inside an ELF binary.
  1128   * ELF binaries can refer to each other using this name.
  1129   * @end deftypefun
  1130  @*/
  1131  const char *jit_readelf_get_name(jit_readelf_t readelf)
  1132  {
  1133  	Elf_Addr value;
  1134  	if(dynamic_for_type(readelf, DT_SONAME, &value))
  1135  	{
  1136  		return get_dyn_string(readelf, value);
  1137  	}
  1138  	else
  1139  	{
  1140  		return 0;
  1141  	}
  1142  }
  1143  
  1144  /*@
  1145   * @deftypefun void *jit_readelf_get_symbol (jit_readelf_t @var{readelf}, const char *@var{name})
  1146   * Look up the symbol called @var{name} in the ELF binary represented
  1147   * by @var{readelf}.  Returns NULL if the symbol is not present.
  1148   *
  1149   * External references from this ELF binary to others are not resolved
  1150   * until the ELF binary is loaded into a JIT context using
  1151   * @code{jit_readelf_add_to_context} and @code{jit_readelf_resolve_all}.
  1152   * You should not call functions within this ELF binary until after you
  1153   * have fully resolved it.
  1154   * @end deftypefun
  1155  @*/
  1156  void *jit_readelf_get_symbol(jit_readelf_t readelf, const char *name)
  1157  {
  1158  	unsigned long hash;
  1159  	unsigned long temp;
  1160  	unsigned int index;
  1161  	jit_nuint num_symbols;
  1162  	Elf_Sym *symbol;
  1163  	const char *symbol_name;
  1164  
  1165  	/* Bail out if we have insufficient information to resolve the name */
  1166  	if(!readelf || !name || !(readelf->symbol_table))
  1167  	{
  1168  		return 0;
  1169  	}
  1170  
  1171  	/* Hash the name to get the starting index in the symbol hash */
  1172  	hash = 0;
  1173  	index = 0;
  1174  	while(name[index] != 0)
  1175  	{
  1176  		hash = (hash << 4) + (unsigned long)(name[index] & 0xFF);
  1177  		temp = (hash & 0xF0000000);
  1178  		if(temp != 0)
  1179  		{
  1180  			hash ^= temp | (temp >> 24);
  1181  		}
  1182  		++index;
  1183  	}
  1184  
  1185  	/* Look in the hash table for the name */
  1186  	if(readelf->symbol_hash_buckets != 0)
  1187  	{
  1188  		hash %= (unsigned long)(readelf->symbol_hash_buckets);
  1189  		temp = (unsigned long)(readelf->symbol_hash[hash + 2]);
  1190  		while(temp != 0 && temp < readelf->symbol_table_size)
  1191  		{
  1192  			symbol = &(readelf->symbol_table[temp]);
  1193  			symbol_name = get_dyn_string(readelf, symbol->st_name);
  1194  			if(symbol_name && !jit_strcmp(symbol_name, name))
  1195  			{
  1196  				/* Ignore symbols in section 0, as they are external */
  1197  				if(symbol->st_shndx)
  1198  				{
  1199  					return jit_readelf_map_vaddr
  1200  						(readelf, (jit_nuint)(symbol->st_value));
  1201  				}
  1202  				break;
  1203  			}
  1204  			temp = (unsigned long)(readelf->symbol_hash
  1205  				[temp + readelf->symbol_hash_buckets + 2]);
  1206  		}
  1207  		return 0;
  1208  	}
  1209  
  1210  	/* There is no hash table, so search for the symbol the hard way */
  1211  	symbol = readelf->symbol_table;
  1212  	for(num_symbols = readelf->symbol_table_size;
  1213  		num_symbols > 0; --num_symbols)
  1214  	{
  1215  		symbol_name = get_dyn_string(readelf, symbol->st_name);
  1216  		if(symbol_name && !jit_strcmp(symbol_name, name))
  1217  		{
  1218  			/* Ignore symbols in section 0, as they are external */
  1219  			if(symbol->st_shndx)
  1220  			{
  1221  				return jit_readelf_map_vaddr
  1222  					(readelf, (jit_nuint)(symbol->st_value));
  1223  			}
  1224  		}
  1225  		++symbol;
  1226  	}
  1227  	return 0;
  1228  }
  1229  
  1230  /*@
  1231   * @deftypefun {void *} jit_readelf_get_section (jit_readelf_t @var{readelf}, const char *@var{name}, jit_nuint *@var{size})
  1232   * Get the address and size of a particular section from an ELF binary.
  1233   * Returns NULL if the section is not present in the ELF binary.
  1234   *
  1235   * The virtual machine may have stored auxillary information
  1236   * in the section when the binary was first generated.  This function
  1237   * allows the virtual machine to retrieve its auxillary information.
  1238   *
  1239   * Examples of such information may be version numbers, timestamps,
  1240   * checksums, and other identifying information for the bytecode that
  1241   * was previously compiled by the virtual machine.  The virtual machine
  1242   * can use this to determine if the ELF binary is up to date and
  1243   * relevant to its needs.
  1244   *
  1245   * It is recommended that virtual machines prefix their special sections
  1246   * with a unique string (e.g. @code{.foovm}) to prevent clashes with
  1247   * system-defined section names.  The prefix @code{.libjit} is reserved
  1248   * for use by @code{libjit} itself.
  1249   * @end deftypefun
  1250  @*/
  1251  void *jit_readelf_get_section
  1252  	(jit_readelf_t readelf, const char *name, jit_nuint *size)
  1253  {
  1254  	unsigned int index;
  1255  	Elf_Shdr *shdr;
  1256  	const char *temp_name;
  1257  	if(!readelf || !name)
  1258  	{
  1259  		return 0;
  1260  	}
  1261  	for(index = 0; index < readelf->ehdr.e_shnum; ++index)
  1262  	{
  1263  		shdr = get_shdr(readelf, index);
  1264  		if(shdr)
  1265  		{
  1266  			temp_name = get_string(readelf, shdr->sh_name);
  1267  			if(temp_name && !jit_strcmp(name, temp_name))
  1268  			{
  1269  				if(size)
  1270  				{
  1271  					*size = (jit_nuint)(shdr->sh_size);
  1272  				}
  1273  				if((shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0)
  1274  				{
  1275  					return (void *)(jit_nuint)(shdr->sh_offset);
  1276  				}
  1277  				else
  1278  				{
  1279  					return jit_readelf_map_vaddr
  1280  						(readelf, (jit_nuint)(shdr->sh_addr));
  1281  				}
  1282  			}
  1283  		}
  1284  	}
  1285  	return 0;
  1286  }
  1287  
  1288  /*@
  1289   * @deftypefun {void *} jit_readelf_get_section_by_type (jit_readelf_t @var{readelf}, jit_int @var{type}, jit_nuint *@var{size})
  1290   * Get a particular section using its raw ELF section type (i.e. one of
  1291   * the @code{SHT_*} constants in @code{jit-elf-defs.h}).  This is mostly
  1292   * for internal use, but some virtual machines may find it useful for
  1293   * debugging purposes.
  1294   * @end deftypefun
  1295  @*/
  1296  void *jit_readelf_get_section_by_type
  1297  	(jit_readelf_t readelf, jit_int type, jit_nuint *size)
  1298  {
  1299  	unsigned int index;
  1300  	Elf_Shdr *shdr;
  1301  	if(!readelf)
  1302  	{
  1303  		return 0;
  1304  	}
  1305  	for(index = 0; index < readelf->ehdr.e_shnum; ++index)
  1306  	{
  1307  		shdr = get_shdr(readelf, index);
  1308  		if(shdr && type == (jit_int)(shdr->sh_type))
  1309  		{
  1310  			if(size)
  1311  			{
  1312  				*size = (jit_nuint)(shdr->sh_size);
  1313  			}
  1314  			if((shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0)
  1315  			{
  1316  				return (void *)(jit_nuint)(shdr->sh_offset);
  1317  			}
  1318  			else
  1319  			{
  1320  				return jit_readelf_map_vaddr
  1321  					(readelf, (jit_nuint)(shdr->sh_addr));
  1322  			}
  1323  		}
  1324  	}
  1325  	return 0;
  1326  }
  1327  
  1328  /*@
  1329   * @deftypefun {void *} jit_readelf_map_vaddr (jit_readelf_t @var{readelf}, jit_nuint @var{vaddr})
  1330   * Map a virtual address to an actual address in a loaded ELF binary.
  1331   * Returns NULL if @var{vaddr} could not be mapped.
  1332   * @end deftypefun
  1333  @*/
  1334  void *jit_readelf_map_vaddr(jit_readelf_t readelf, jit_nuint vaddr)
  1335  {
  1336  	unsigned int index;
  1337  	Elf_Phdr *phdr;
  1338  	if(!readelf)
  1339  	{
  1340  		return 0;
  1341  	}
  1342  	for(index = 0; index < readelf->ehdr.e_phnum; ++index)
  1343  	{
  1344  		phdr = get_phdr(readelf, index);
  1345  		if(phdr && vaddr >= phdr->p_vaddr &&
  1346  		   vaddr < (phdr->p_vaddr + phdr->p_memsz))
  1347  		{
  1348  			return (void *)(((unsigned char *)(readelf->map_address)) + vaddr);
  1349  		}
  1350  	}
  1351  	return 0;
  1352  }
  1353  
  1354  /*@
  1355   * @deftypefun {unsigned int} jit_readelf_num_needed (jit_readelf_t @var{readelf})
  1356   * Get the number of dependent libraries that are needed by this
  1357   * ELF binary.  The virtual machine will normally need to arrange
  1358   * to load these libraries with @code{jit_readelf_open} as well,
  1359   * so that all of the necessary symbols can be resolved.
  1360   * @end deftypefun
  1361  @*/
  1362  unsigned int jit_readelf_num_needed(jit_readelf_t readelf)
  1363  {
  1364  	jit_dynamic_iter_t iter;
  1365  	unsigned int count = 0;
  1366  	jit_uint type;
  1367  	Elf_Addr value;
  1368  	dynamic_iter_init(&iter, readelf);
  1369  	while(dynamic_iter_next(&iter, &type, &value))
  1370  	{
  1371  		if(type == DT_NEEDED)
  1372  		{
  1373  			++count;
  1374  		}
  1375  	}
  1376  	return count;
  1377  }
  1378  
  1379  /*@
  1380   * @deftypefun {const char *} jit_readelf_get_needed (jit_readelf_t @var{readelf}, unsigned int @var{index})
  1381   * Get the name of the dependent library at position @var{index} within
  1382   * the needed libraries list of this ELF binary.  Returns NULL if
  1383   * the @var{index} is invalid.
  1384   * @end deftypefun
  1385  @*/
  1386  const char *jit_readelf_get_needed(jit_readelf_t readelf, unsigned int index)
  1387  {
  1388  	jit_dynamic_iter_t iter;
  1389  	jit_uint type;
  1390  	Elf_Addr value;
  1391  	dynamic_iter_init(&iter, readelf);
  1392  	while(dynamic_iter_next(&iter, &type, &value))
  1393  	{
  1394  		if(type == DT_NEEDED)
  1395  		{
  1396  			if(index == 0)
  1397  			{
  1398  				return get_dyn_string(readelf, value);
  1399  			}
  1400  			--index;
  1401  		}
  1402  	}
  1403  	return 0;
  1404  }
  1405  
  1406  /*@
  1407   * @deftypefun void jit_readelf_add_to_context (jit_readelf_t @var{readelf}, jit_context_t @var{context})
  1408   * Add this ELF binary to a JIT context, so that its contents can be used
  1409   * when executing JIT-managed code.  The binary will be closed automatically
  1410   * if the context is destroyed and @code{jit_readelf_close} has not been
  1411   * called explicitly yet.
  1412   *
  1413   * The functions in the ELF binary cannot be used until you also call
  1414   * @code{jit_readelf_resolve_all} to resolve cross-library symbol references.
  1415   * The reason why adding and resolution are separate steps is to allow for
  1416   * resolving circular dependencies between ELF binaries.
  1417   * @end deftypefun
  1418  @*/
  1419  void jit_readelf_add_to_context(jit_readelf_t readelf, jit_context_t context)
  1420  {
  1421  	if(!readelf || !context)
  1422  	{
  1423  		return;
  1424  	}
  1425  
  1426  	_jit_memory_lock(context);
  1427  
  1428  	readelf->next = context->elf_binaries;
  1429  	context->elf_binaries = readelf;
  1430  
  1431  	_jit_memory_unlock(context);
  1432  }
  1433  
  1434  /*
  1435   * Import the internal symbol table from "jit-symbol.c".
  1436   */
  1437  typedef struct
  1438  {
  1439  	const char *name;
  1440  	void       *value;
  1441  
  1442  } jit_internalsym;
  1443  extern jit_internalsym const _jit_internal_symbols[];
  1444  extern int const _jit_num_internal_symbols;
  1445  
  1446  /*
  1447   * Resolve a symbol to an address.
  1448   */
  1449  static void *resolve_symbol
  1450  	(jit_context_t context, jit_readelf_t readelf,
  1451  	 int print_failures, const char *name, jit_nuint symbol)
  1452  {
  1453  	Elf_Sym *sym;
  1454  	void *value;
  1455  	const char *symbol_name;
  1456  	jit_readelf_t library;
  1457  	int index, left, right, cmp;
  1458  
  1459  	/* Find the actual symbol details */
  1460  	if(symbol >= readelf->symbol_table_size)
  1461  	{
  1462  		if(print_failures)
  1463  		{
  1464  			printf("%s: invalid symbol table index %lu\n",
  1465  				   name, (unsigned long)symbol);
  1466  		}
  1467  		return 0;
  1468  	}
  1469  	sym = &(readelf->symbol_table[symbol]);
  1470  
  1471  	/* Does the symbol have a locally-defined value? */
  1472  	if(sym->st_value)
  1473  	{
  1474  		value = jit_readelf_map_vaddr(readelf, (jit_nuint)(sym->st_value));
  1475  		if(!value)
  1476  		{
  1477  			if(print_failures)
  1478  			{
  1479  				printf("%s: could not map virtual address 0x%lx\n",
  1480  					   name, (long)(sym->st_value));
  1481  			}
  1482  		}
  1483  		return value;
  1484  	}
  1485  
  1486  	/* Get the symbol's name, so that we can look it up in other libraries */
  1487  	symbol_name = get_dyn_string(readelf, sym->st_name);
  1488  	if(!symbol_name)
  1489  	{
  1490  		if(print_failures)
  1491  		{
  1492  			printf("%s: symbol table index %lu does not have a valid name\n",
  1493  				   name, (unsigned long)symbol);
  1494  		}
  1495  		return 0;
  1496  	}
  1497  
  1498  	/* Look for "before" symbols that are registered with the context */
  1499  	for(index = 0; index < context->num_registered_symbols; ++index)
  1500  	{
  1501  		if(!jit_strcmp(symbol_name, context->registered_symbols[index]->name) &&
  1502  		   !(context->registered_symbols[index]->after))
  1503  		{
  1504  			return context->registered_symbols[index]->value;
  1505  		}
  1506  	}
  1507  
  1508  	/* Search all loaded ELF libraries for the name */
  1509  	library = context->elf_binaries;
  1510  	while(library != 0)
  1511  	{
  1512  		value = jit_readelf_get_symbol(library, symbol_name);
  1513  		if(value)
  1514  		{
  1515  			return value;
  1516  		}
  1517  		library = library->next;
  1518  	}
  1519  
  1520  	/* Look for libjit internal symbols (i.e. intrinsics) */
  1521  	left = 0;
  1522  	right = _jit_num_internal_symbols - 1;
  1523  	while(left <= right)
  1524  	{
  1525  		index = (left + right) / 2;
  1526  		cmp = jit_strcmp(symbol_name, _jit_internal_symbols[index].name);
  1527  		if(cmp == 0)
  1528  		{
  1529  			return _jit_internal_symbols[index].value;
  1530  		}
  1531  		else if(cmp < 0)
  1532  		{
  1533  			right = index - 1;
  1534  		}
  1535  		else
  1536  		{
  1537  			left = index + 1;
  1538  		}
  1539  	}
  1540  
  1541  	/* Look for "after" symbols that are registered with the context */
  1542  	for(index = 0; index < context->num_registered_symbols; ++index)
  1543  	{
  1544  		if(!jit_strcmp(symbol_name, context->registered_symbols[index]->name) &&
  1545  		   context->registered_symbols[index]->after)
  1546  		{
  1547  			return context->registered_symbols[index]->value;
  1548  		}
  1549  	}
  1550  
  1551  	/* If we get here, then we could not resolve the symbol */
  1552  	printf("%s: could not resolve `%s'\n", name, symbol_name);
  1553  	return 0;
  1554  }
  1555  
  1556  /*
  1557   * Perform a DT_REL style relocation on an ELF binary.
  1558   */
  1559  static int perform_rel
  1560  	(jit_context_t context, jit_readelf_t readelf, 
  1561  	 int print_failures, const char *name, Elf_Rel *reloc)
  1562  {
  1563  	void *address;
  1564  	void *value;
  1565  
  1566  	/* Get the address to apply the relocation at */
  1567  	address = jit_readelf_map_vaddr(readelf, (jit_nuint)(reloc->r_offset));
  1568  	if(!address)
  1569  	{
  1570  		if(print_failures)
  1571  		{
  1572  			printf("%s: cannot map virtual address 0x%lx\n",
  1573  				   name, (long)(reloc->r_offset));
  1574  		}
  1575  		return 0;
  1576  	}
  1577  
  1578  	/* Resolve the designated symbol to its actual value */
  1579  	value = resolve_symbol
  1580  		(context, readelf, print_failures, name,
  1581  		 (jit_nuint)ELF_R_SYM(reloc->r_info));
  1582  	if(!value)
  1583  	{
  1584  		return 0;
  1585  	}
  1586  
  1587  	/* Perform the relocation */
  1588  	if(!(*(readelf->reloc_func))
  1589  		(readelf, address, (int)(ELF_R_TYPE(reloc->r_info)),
  1590  		 (jit_nuint)value, 0, 0))
  1591  	{
  1592  		if(print_failures)
  1593  		{
  1594  			printf("%s: relocation type %d was not recognized\n",
  1595  				   name, (int)(ELF_R_TYPE(reloc->r_info)));
  1596  		}
  1597  		return 0;
  1598  	}
  1599  	return 1;
  1600  }
  1601  
  1602  /*
  1603   * Perform a DT_RELA style relocation on an ELF binary.
  1604   */
  1605  static int perform_rela
  1606  	(jit_context_t context, jit_readelf_t readelf,
  1607  	 int print_failures, const char *name, Elf_Rela *reloc)
  1608  {
  1609  	void *address;
  1610  	void *value;
  1611  
  1612  	/* Get the address to apply the relocation at */
  1613  	address = jit_readelf_map_vaddr(readelf, (jit_nuint)(reloc->r_offset));
  1614  	if(!address)
  1615  	{
  1616  		if(print_failures)
  1617  		{
  1618  			printf("%s: cannot map virtual address 0x%lx\n",
  1619  				   name, (long)(reloc->r_offset));
  1620  		}
  1621  		return 0;
  1622  	}
  1623  
  1624  	/* Resolve the designated symbol to its actual value */
  1625  	value = resolve_symbol
  1626  		(context, readelf, print_failures, name,
  1627  		 (jit_nuint)ELF_R_SYM(reloc->r_info));
  1628  	if(!value)
  1629  	{
  1630  		return 0;
  1631  	}
  1632  
  1633  	/* Perform the relocation */
  1634  	if(!(*(readelf->reloc_func))
  1635  		(readelf, address, (int)(ELF_R_TYPE(reloc->r_info)),
  1636  		 (jit_nuint)value, 1, (jit_nuint)(reloc->r_addend)))
  1637  	{
  1638  		if(print_failures)
  1639  		{
  1640  			printf("%s: relocation type %d was not recognized\n",
  1641  				   name, (int)(ELF_R_TYPE(reloc->r_info)));
  1642  		}
  1643  		return 0;
  1644  	}
  1645  	return 1;
  1646  }
  1647  
  1648  /*
  1649   * Perform relocations on an ELF binary.  Returns zero on failure.
  1650   */
  1651  static int perform_relocations
  1652  	(jit_context_t context, jit_readelf_t readelf, int print_failures)
  1653  {
  1654  	Elf_Addr address;
  1655  	Elf_Addr table_size;
  1656  	Elf_Addr entry_size;
  1657  	unsigned char *table;
  1658  	const char *name;
  1659  	int ok = 1;
  1660  
  1661  	/* Get the library name, for printing diagnostic messages */
  1662  	name = jit_readelf_get_name(readelf);
  1663  	if(!name)
  1664  	{
  1665  		name = "unknown-elf-binary";
  1666  	}
  1667  
  1668  	/* Bail out if we don't know how to perform relocations */
  1669  	if(!(readelf->reloc_func))
  1670  	{
  1671  		if(print_failures)
  1672  		{
  1673  			printf("%s: do not know how to perform relocations\n", name);
  1674  		}
  1675  		return 0;
  1676  	}
  1677  
  1678  	/* Apply the "Rel" relocations in the dynamic section */
  1679  	if(dynamic_for_type(readelf, DT_REL, &address) &&
  1680  	   dynamic_for_type(readelf, DT_RELSZ, &table_size) &&
  1681  	   dynamic_for_type(readelf, DT_RELENT, &entry_size) && entry_size)
  1682  	{
  1683  		table = (unsigned char *)jit_readelf_map_vaddr
  1684  			(readelf, (jit_nuint)address);
  1685  		while(table && table_size >= entry_size)
  1686  		{
  1687  			if(!perform_rel(context, readelf, print_failures, name,
  1688  					        (Elf_Rel *)table))
  1689  			{
  1690  				ok = 0;
  1691  			}
  1692  			table += (jit_nuint)entry_size;
  1693  			table_size -= entry_size;
  1694  		}
  1695  	}
  1696  
  1697  	/* Apply the "Rela" relocations in the dynamic section */
  1698  	if(dynamic_for_type(readelf, DT_RELA, &address) &&
  1699  	   dynamic_for_type(readelf, DT_RELASZ, &table_size) &&
  1700  	   dynamic_for_type(readelf, DT_RELAENT, &entry_size) && entry_size)
  1701  	{
  1702  		table = (unsigned char *)jit_readelf_map_vaddr
  1703  			(readelf, (jit_nuint)address);
  1704  		while(table && table_size >= entry_size)
  1705  		{
  1706  			if(!perform_rela(context, readelf, print_failures, name,
  1707  					         (Elf_Rela *)table))
  1708  			{
  1709  				ok = 0;
  1710  			}
  1711  			table += (jit_nuint)entry_size;
  1712  			table_size -= entry_size;
  1713  		}
  1714  	}
  1715  
  1716  	/* Apply the "PLT" relocations in the dynamic section, which
  1717  	   may be either DT_REL or DT_RELA style relocations */
  1718  	if(dynamic_for_type(readelf, DT_JMPREL, &address) &&
  1719  	   dynamic_for_type(readelf, DT_PLTRELSZ, &table_size) &&
  1720  	   dynamic_for_type(readelf, DT_PLTREL, &entry_size))
  1721  	{
  1722  		if(entry_size == DT_REL)
  1723  		{
  1724  			if(dynamic_for_type(readelf, DT_RELENT, &entry_size) && entry_size)
  1725  			{
  1726  				table = (unsigned char *)jit_readelf_map_vaddr
  1727  					(readelf, (jit_nuint)address);
  1728  				while(table && table_size >= entry_size)
  1729  				{
  1730  					if(!perform_rel(context, readelf, print_failures, name,
  1731  							        (Elf_Rel *)table))
  1732  					{
  1733  						ok = 0;
  1734  					}
  1735  					table += (jit_nuint)entry_size;
  1736  					table_size -= entry_size;
  1737  				}
  1738  			}
  1739  		}
  1740  		else if(entry_size == DT_RELA)
  1741  		{
  1742  			if(dynamic_for_type(readelf, DT_RELAENT, &entry_size) && entry_size)
  1743  			{
  1744  				table = (unsigned char *)jit_readelf_map_vaddr
  1745  					(readelf, (jit_nuint)address);
  1746  				while(table && table_size >= entry_size)
  1747  				{
  1748  					if(!perform_rela(context, readelf, print_failures, name,
  1749  							         (Elf_Rela *)table))
  1750  					{
  1751  						ok = 0;
  1752  					}
  1753  					table += (jit_nuint)entry_size;
  1754  					table_size -= entry_size;
  1755  				}
  1756  			}
  1757  		}
  1758  	}
  1759  
  1760  	/* Return to the caller */
  1761  	return ok;
  1762  }
  1763  
  1764  /*@
  1765   * @deftypefun int jit_readelf_resolve_all (jit_context_t @var{context}, int @var{print_failures})
  1766   * Resolve all of the cross-library symbol references in ELF binaries
  1767   * that have been added to @var{context} but which were not resolved
  1768   * in the previous call to this function.  If @var{print_failures}
  1769   * is non-zero, then diagnostic messages will be written to stdout
  1770   * for any symbol resolutions that fail.
  1771   *
  1772   * Returns zero on failure, or non-zero if all symbols were successfully
  1773   * resolved.  If there are no ELF binaries awaiting resolution, then
  1774   * this function will return a non-zero result.
  1775   * @end deftypefun
  1776  @*/
  1777  int jit_readelf_resolve_all(jit_context_t context, int print_failures)
  1778  {
  1779  	int ok = 1;
  1780  	jit_readelf_t readelf;
  1781  	if(!context)
  1782  	{
  1783  		return 0;
  1784  	}
  1785  
  1786  	_jit_memory_lock(context);
  1787  
  1788  	readelf = context->elf_binaries;
  1789  	while(readelf != 0)
  1790  	{
  1791  		if(!(readelf->resolved))
  1792  		{
  1793  			readelf->resolved = 1;
  1794  			if(!perform_relocations(context, readelf, print_failures))
  1795  			{
  1796  				ok = 0;
  1797  			}
  1798  		}
  1799  		readelf = readelf->next;
  1800  	}
  1801  
  1802  	_jit_memory_unlock(context);
  1803  	return ok;
  1804  }
  1805  
  1806  /*@
  1807   * @deftypefun int jit_readelf_register_symbol (jit_context_t @var{context}, const char *@var{name}, void *@var{value}, int @var{after})
  1808   * Register @var{value} with @var{name} on the specified @var{context}.
  1809   * Whenever symbols are resolved with @code{jit_readelf_resolve_all},
  1810   * and the symbol @var{name} is encountered, @var{value} will be
  1811   * substituted.  Returns zero if out of memory or there is something
  1812   * wrong with the parameters.
  1813   *
  1814   * If @var{after} is non-zero, then @var{name} will be resolved after all
  1815   * other ELF libraries; otherwise it will be resolved before the ELF
  1816   * libraries.
  1817   *
  1818   * This function is used to register intrinsic symbols that are specific to
  1819   * the front end virtual machine.  References to intrinsics within
  1820   * @code{libjit} itself are resolved automatically.
  1821   * @end deftypefun
  1822  @*/
  1823  int jit_readelf_register_symbol
  1824  	(jit_context_t context, const char *name, void *value, int after)
  1825  {
  1826  	jit_regsym_t sym;
  1827  	jit_regsym_t *new_list;
  1828  
  1829  	/* Bail out if there is something wrong with the parameters */
  1830  	if(!context || !name || !value)
  1831  	{
  1832  		return 0;
  1833  	}
  1834  
  1835  	/* Allocate and populate the symbol information block */
  1836  	sym = (jit_regsym_t)jit_malloc
  1837  		(sizeof(struct jit_regsym) + jit_strlen(name));
  1838  	if(!sym)
  1839  	{
  1840  		return 0;
  1841  	}
  1842  	sym->value = value;
  1843  	sym->after = after;
  1844  	jit_strcpy(sym->name, name);
  1845  
  1846  	/* Add the symbol details to the registered list */
  1847  	new_list = (jit_regsym_t *)jit_realloc
  1848  		(context->registered_symbols,
  1849  		 sizeof(jit_regsym_t) * (context->num_registered_symbols + 1));
  1850  	if(!new_list)
  1851  	{
  1852  		jit_free(sym);
  1853  		return 0;
  1854  	}
  1855  	new_list[(context->num_registered_symbols)++] = sym;
  1856  	context->registered_symbols = new_list;
  1857  	return 1;
  1858  }
  1859  
  1860  /************************************************************************
  1861  
  1862  		             Warning!  Warning!  Warning!
  1863  
  1864  The following code is very system-dependent, as every ELF target has its
  1865  own peculiar mechanism for performing relocations.  Consult your target's
  1866  documentation for the precise details.
  1867  
  1868  To make things a little easier, you only need to support the relocation
  1869  types that you intend to use in the JIT's ELF writer.  And many types
  1870  only pertain to ELF executable or object files, which we don't use.
  1871  
  1872  ************************************************************************/
  1873  
  1874  #if defined(__i386) || defined(__i386__) || defined(_M_IX86)
  1875  
  1876  /*
  1877   * Apply relocations for i386 platforms.
  1878   */
  1879  static int i386_reloc(jit_readelf_t readelf, void *address, int type,
  1880  					  jit_nuint value, int has_addend, jit_nuint addend)
  1881  {
  1882  	if(type == R_386_32)
  1883  	{
  1884  		if(has_addend)
  1885  		{
  1886  			*((jit_nuint *)address) = value + addend;
  1887  		}
  1888  		else
  1889  		{
  1890  			*((jit_nuint *)address) += value;
  1891  		}
  1892  		return 1;
  1893  	}
  1894  	else if(type == R_386_PC32)
  1895  	{
  1896  		value -= (jit_nuint)address;
  1897  		if(has_addend)
  1898  		{
  1899  			*((jit_nuint *)address) = value + addend;
  1900  		}
  1901  		else
  1902  		{
  1903  			*((jit_nuint *)address) += value;
  1904  		}
  1905  		return 1;
  1906  	}
  1907  	return 0;
  1908  }
  1909  
  1910  #endif /* i386 */
  1911  
  1912  #if defined(__arm) || defined(__arm__)
  1913  
  1914  /*
  1915   * Apply relocations for ARM platforms.
  1916   */
  1917  static int arm_reloc(jit_readelf_t readelf, void *address, int type,
  1918  					 jit_nuint value, int has_addend, jit_nuint addend)
  1919  {
  1920  	if(type == R_ARM_PC24)
  1921  	{
  1922  		value -= (jit_nuint)address;
  1923  		if(has_addend)
  1924  		{
  1925  			*((jit_nuint *)address) =
  1926  				(*((jit_nuint *)address) & 0xFF000000) + value + addend;
  1927  		}
  1928  		else
  1929  		{
  1930  			*((jit_nuint *)address) += value;
  1931  		}
  1932  		return 1;
  1933  	}
  1934  	else if(type == R_ARM_ABS32)
  1935  	{
  1936  		if(has_addend)
  1937  		{
  1938  			*((jit_nuint *)address) = value + addend;
  1939  		}
  1940  		else
  1941  		{
  1942  			*((jit_nuint *)address) += value;
  1943  		}
  1944  		return 1;
  1945  	}
  1946  	else if(type == R_ARM_REL32)
  1947  	{
  1948  		value -= (jit_nuint)address;
  1949  		if(has_addend)
  1950  		{
  1951  			*((jit_nuint *)address) = value + addend;
  1952  		}
  1953  		else
  1954  		{
  1955  			*((jit_nuint *)address) += value;
  1956  		}
  1957  		return 1;
  1958  	}
  1959  	return 0;
  1960  }
  1961  
  1962  #endif /* arm */
  1963  
  1964  /*
  1965   * Apply relocations for the interpreted platform.
  1966   */
  1967  static int interp_reloc(jit_readelf_t readelf, void *address, int type,
  1968  						jit_nuint value, int has_addend, jit_nuint addend)
  1969  {
  1970  	/* We only have one type of relocation for the interpreter: direct */
  1971  	if(type == 1)
  1972  	{
  1973  		*((jit_nuint *)address) = value;
  1974  		return 1;
  1975  	}
  1976  	else
  1977  	{
  1978  		return 0;
  1979  	}
  1980  }
  1981  
  1982  /*
  1983   * Get the relocation function for a particular machine type.
  1984   */
  1985  static jit_reloc_func get_reloc(unsigned int machine)
  1986  {
  1987  #if defined(__i386) || defined(__i386__) || defined(_M_IX86)
  1988  	if(machine == EM_386)
  1989  	{
  1990  		return i386_reloc;
  1991  	}
  1992  #endif
  1993  #if defined(__arm) || defined(__arm__)
  1994  	if(machine == EM_ARM)
  1995  	{
  1996  		return arm_reloc;
  1997  	}
  1998  #endif
  1999  	if(machine == 0x4C6A)		/* "Lj" for the libjit interpreter */
  2000  	{
  2001  		return interp_reloc;
  2002  	}
  2003  	return 0;
  2004  }