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

     1  /*
     2   * jit-elf-write.c - Routines to write 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-elf-defs.h"
    25  #include "jit-rules.h"
    26  
    27  /*@
    28  
    29  @section Writing ELF binaries
    30  
    31  @*/
    32  
    33  /*
    34   * Determine whether we should be using the 32-bit or 64-bit ELF structures.
    35   */
    36  #ifdef JIT_NATIVE_INT32
    37  	typedef Elf32_Ehdr  Elf_Ehdr;
    38  	typedef Elf32_Shdr  Elf_Shdr;
    39  	typedef Elf32_Phdr  Elf_Phdr;
    40  	typedef Elf32_Addr  Elf_Addr;
    41  	typedef Elf32_Half  Elf_Half;
    42  	typedef Elf32_Word  Elf_Word;
    43  	typedef Elf32_Xword Elf_Xword;
    44  	typedef Elf32_Off   Elf_Off;
    45  	typedef Elf32_Dyn   Elf_Dyn;
    46  	typedef Elf32_Sym   Elf_Sym;
    47  #else
    48  	typedef Elf64_Ehdr  Elf_Ehdr;
    49  	typedef Elf64_Shdr  Elf_Shdr;
    50  	typedef Elf64_Phdr  Elf_Phdr;
    51  	typedef Elf64_Addr  Elf_Addr;
    52  	typedef Elf64_Half  Elf_Half;
    53  	typedef Elf64_Word  Elf_Word;
    54  	typedef Elf64_Xword Elf_Xword;
    55  	typedef Elf64_Off   Elf_Off;
    56  	typedef Elf64_Dyn   Elf_Dyn;
    57  	typedef Elf64_Sym   Elf_Sym;
    58  #endif
    59  
    60  /*
    61   * Information about the contents of a section.
    62   */
    63  typedef struct jit_section *jit_section_t;
    64  struct jit_section
    65  {
    66  	Elf_Shdr			shdr;
    67  	char			   *data;
    68  	unsigned int		data_len;
    69  };
    70  
    71  /*
    72   * Control structure for writing an ELF binary.
    73   */
    74  struct jit_writeelf
    75  {
    76  	Elf_Ehdr			ehdr;
    77  	jit_section_t	    sections;
    78  	int					num_sections;
    79  	int					regular_string_section;
    80  	int					dynamic_string_section;
    81  };
    82  
    83  /*
    84   * Get a string from the regular string section.
    85   */
    86  static const char *get_string(jit_writeelf_t writeelf, Elf_Word index)
    87  {
    88  	if(writeelf->regular_string_section < 0)
    89  	{
    90  		/* The regular string section has not been created yet */
    91  		return 0;
    92  	}
    93  	else
    94  	{
    95  		/* Retrieve the pointer to the string's starting point */
    96  		return writeelf->sections[writeelf->regular_string_section].data +
    97  					(jit_nuint)index;
    98  	}
    99  }
   100  
   101  /*
   102   * Add a string to the regular string section.  We don't worry about
   103   * duplicate names because we only store section names here.  And
   104   * section names are only added when a new section is created.
   105   */
   106  static Elf_Word add_string(jit_writeelf_t writeelf, const char *name)
   107  {
   108  	jit_section_t section;
   109  	char *data;
   110  	Elf_Word index;
   111  	unsigned int name_len = jit_strlen(name) + 1;
   112  	section = &(writeelf->sections[writeelf->regular_string_section]);
   113  	data = (char *)jit_realloc(section->data, section->data_len + name_len);
   114  	if(!data)
   115  	{
   116  		return 0;
   117  	}
   118  	section->data = data;
   119  	jit_strcpy(data + section->data_len, name);
   120  	index = (Elf_Word)(section->data_len);
   121  	section->data_len += name_len;
   122  	return index;
   123  }
   124  
   125  /*
   126   * Get a string from the dynamic string section.
   127   */
   128  static const char *get_dyn_string(jit_writeelf_t writeelf, Elf_Word index)
   129  {
   130  	if(writeelf->dynamic_string_section < 0)
   131  	{
   132  		/* The dynamic string section has not been created yet */
   133  		return 0;
   134  	}
   135  	else
   136  	{
   137  		/* Retrieve the pointer to the string's starting point */
   138  		return writeelf->sections[writeelf->dynamic_string_section].data +
   139  					(jit_nuint)index;
   140  	}
   141  }
   142  
   143  /*
   144   * Add a string to the dynamic string section.
   145   *
   146   * TODO: use a hash table to cache previous names.
   147   */
   148  static Elf_Word add_dyn_string(jit_writeelf_t writeelf, const char *name)
   149  {
   150  	jit_section_t section;
   151  	char *data;
   152  	Elf_Word index;
   153  	unsigned int name_len = jit_strlen(name) + 1;
   154  	section = &(writeelf->sections[writeelf->dynamic_string_section]);
   155  	data = (char *)jit_realloc(section->data, section->data_len + name_len);
   156  	if(!data)
   157  	{
   158  		return 0;
   159  	}
   160  	section->data = data;
   161  	jit_strcpy(data + section->data_len, name);
   162  	index = (Elf_Word)(section->data_len);
   163  	section->data_len += name_len;
   164  	return index;
   165  }
   166  
   167  /*
   168   * Get or add a section.
   169   */
   170  static jit_section_t get_section
   171  	(jit_writeelf_t writeelf, const char *name, jit_int type,
   172  	 Elf_Word flags, Elf_Word entry_size, Elf_Word alignment)
   173  {
   174  	int index;
   175  	jit_section_t section;
   176  
   177  	/* Search the section table for an existing section by this name */
   178  	for(index = 0; index < writeelf->num_sections; ++index)
   179  	{
   180  		section = &(writeelf->sections[index]);
   181  		if(!jit_strcmp(get_string(writeelf, section->shdr.sh_name), name))
   182  		{
   183  			return section;
   184  		}
   185  	}
   186  
   187  	/* Create a new section and clear it */
   188  	section = (jit_section_t)jit_realloc
   189  		(writeelf->sections,
   190  		 (writeelf->num_sections + 1) * sizeof(struct jit_section));
   191  	if(!section)
   192  	{
   193  		return 0;
   194  	}
   195  	writeelf->sections = section;
   196  	section += writeelf->num_sections;
   197  	jit_memzero(section, sizeof(struct jit_section));
   198  
   199  	/* Set the section's name.  If this is the first section created,
   200  	   then it is the string table itself, and we have to add the
   201  	   name to the section itself to start the ball rolling */
   202  	if(writeelf->regular_string_section < 0)
   203  	{
   204  		section->data = (char *)jit_malloc(jit_strlen(name) + 2);
   205  		if(!(section->data))
   206  		{
   207  			return 0;
   208  		}
   209  		section->data_len = jit_strlen(name) + 2;
   210  		section->data[0] = '\0';	/* Empty string is always first */
   211  		jit_strcpy(section->data + 1, name);
   212  		section->shdr.sh_name = 1;
   213  		writeelf->regular_string_section = writeelf->num_sections;
   214  	}
   215  	else
   216  	{
   217  		section->shdr.sh_name = add_string(writeelf, name);
   218  		if(!(section->shdr.sh_name))
   219  		{
   220  			return 0;
   221  		}
   222  	}
   223  
   224  	/* Set the other section properties */
   225  	section->shdr.sh_type = (Elf_Word)type;
   226  	section->shdr.sh_flags = flags;
   227  	section->shdr.sh_entsize = entry_size;
   228  	section->shdr.sh_addralign = alignment;
   229  
   230  	/* Increase the section count and return */
   231  	++(writeelf->num_sections);
   232  	return section;
   233  }
   234  
   235  /*
   236   * Append data to a section.
   237   */
   238  static int add_to_section
   239  	(jit_section_t section, const void *buf, unsigned int len)
   240  {
   241  	char *data = (char *)jit_realloc(section->data, section->data_len + len);
   242  	if(!data)
   243  	{
   244  		return 0;
   245  	}
   246  	section->data = data;
   247  	jit_memcpy(data + section->data_len, buf, len);
   248  	section->data_len += len;
   249  	return 1;
   250  }
   251  
   252  /*
   253   * Add an entry to the dynamic linking information section.
   254   */
   255  static int add_dyn_info
   256  	(jit_writeelf_t writeelf, int type, Elf_Addr value, int modify_existing)
   257  {
   258  	jit_section_t section;
   259  	Elf_Dyn dyn;
   260  
   261  	/* Get or create the ".dynamic" section */
   262  	section = get_section(writeelf, ".dynamic", SHT_DYNAMIC,
   263  						  SHF_WRITE | SHF_ALLOC,
   264  						  sizeof(Elf_Dyn), sizeof(Elf_Dyn));
   265  	if(!section)
   266  	{
   267  		return 0;
   268  	}
   269  
   270  	/* See if we already have this entry, and modify it as appropriate */
   271  	if(modify_existing)
   272  	{
   273  		Elf_Dyn *existing = (Elf_Dyn *)(section->data);
   274  		unsigned int num = section->data_len / sizeof(Elf_Dyn);
   275  		while(num > 0)
   276  		{
   277  			if(existing->d_tag == type)
   278  			{
   279  				existing->d_un.d_ptr = value;
   280  				return 1;
   281  			}
   282  			++existing;
   283  			--num;
   284  		}
   285  	}
   286  
   287  	/* Format the dynamic entry */
   288  	jit_memzero(&dyn, sizeof(dyn));
   289  	dyn.d_tag = type;
   290  	dyn.d_un.d_ptr = value;
   291  
   292  	/* Add the entry to the section's contents */
   293  	return add_to_section(section, &dyn, sizeof(dyn));
   294  }
   295  
   296  /*@
   297   * @deftypefun jit_writeelf_t jit_writeelf_create (const char *@var{library_name})
   298   * Create an object to assist with the process of writing an ELF binary.
   299   * The @var{library_name} will be embedded into the binary.  Returns NULL
   300   * if out of memory.
   301   * @end deftypefun
   302  @*/
   303  jit_writeelf_t jit_writeelf_create(const char *library_name)
   304  {
   305  	jit_writeelf_t writeelf;
   306  	Elf_Word name_index;
   307  	union
   308  	{
   309  		jit_ushort value;
   310  		unsigned char bytes[2];
   311  
   312  	} un;
   313  	jit_elf_info_t elf_info;
   314  
   315  	/* Create the writer control structure */
   316  	writeelf = jit_cnew(struct jit_writeelf);
   317  	if(!writeelf)
   318  	{
   319  		return 0;
   320  	}
   321  	writeelf->regular_string_section = -1;
   322  	writeelf->dynamic_string_section = -1;
   323  
   324  	/* Create the regular string section for section names,
   325  	   which must be the first section that we create */
   326  	if(!get_section(writeelf, ".shstrtab", SHT_STRTAB, 0, 0, 0))
   327  	{
   328  		jit_writeelf_destroy(writeelf);
   329  		return 0;
   330  	}
   331  
   332  	/* Create the dynamic string section, for dynamic linking symbols */
   333  	if(!get_section(writeelf, ".dynstr", SHT_STRTAB, SHF_ALLOC, 0, 0))
   334  	{
   335  		jit_writeelf_destroy(writeelf);
   336  		return 0;
   337  	}
   338  	writeelf->dynamic_string_section = writeelf->num_sections - 1;
   339  	if(!add_dyn_string(writeelf, ""))
   340  	{
   341  		jit_writeelf_destroy(writeelf);
   342  		return 0;
   343  	}
   344  
   345  	/* Add the library name to the dynamic linking information section */
   346  	name_index = add_dyn_string(writeelf, library_name);
   347  	if(!name_index)
   348  	{
   349  		jit_writeelf_destroy(writeelf);
   350  		return 0;
   351  	}
   352  	if(!add_dyn_info(writeelf, DT_SONAME, (Elf_Addr)name_index, 0))
   353  	{
   354  		jit_writeelf_destroy(writeelf);
   355  		return 0;
   356  	}
   357  
   358  	/* Fill in the Ehdr fields */
   359  	writeelf->ehdr.e_ident[EI_MAG0] = ELFMAG0;
   360  	writeelf->ehdr.e_ident[EI_MAG1] = ELFMAG1;
   361  	writeelf->ehdr.e_ident[EI_MAG2] = ELFMAG2;
   362  	writeelf->ehdr.e_ident[EI_MAG3] = ELFMAG3;
   363  #ifdef JIT_NATIVE_INT32
   364  	writeelf->ehdr.e_ident[EI_CLASS] = ELFCLASS32;
   365  #else
   366  	writeelf->ehdr.e_ident[EI_CLASS] = ELFCLASS64;
   367  #endif
   368  	un.value = 0x0102;
   369  	if(un.bytes[0] == 0x01)
   370  	{
   371  		writeelf->ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
   372  	}
   373  	else
   374  	{
   375  		writeelf->ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
   376  	}
   377  	writeelf->ehdr.e_ident[EI_VERSION] = EV_CURRENT;
   378  	_jit_gen_get_elf_info(&elf_info);
   379  	writeelf->ehdr.e_ident[EI_OSABI] = (unsigned char)(elf_info.abi);
   380  	writeelf->ehdr.e_ident[EI_ABIVERSION] =
   381  		(unsigned char)(elf_info.abi_version);
   382  	writeelf->ehdr.e_machine = (Elf_Half)(elf_info.machine);
   383  	writeelf->ehdr.e_version = EV_CURRENT;
   384  	writeelf->ehdr.e_ehsize = sizeof(writeelf->ehdr);
   385  
   386  	/* Every ELF binary that we generate will need "libjit.so" */
   387  	if(!jit_writeelf_add_needed(writeelf, "libjit.so"))
   388  	{
   389  		jit_writeelf_destroy(writeelf);
   390  		return 0;
   391  	}
   392  
   393  	/* We are ready to go */
   394  	return writeelf;
   395  }
   396  
   397  /*@
   398   * @deftypefun void jit_writeelf_destroy (jit_writeelf_t @var{writeelf})
   399   * Destroy the memory structures that were used while @var{writeelf}
   400   * was being built.
   401   * @end deftypefun
   402  @*/
   403  void jit_writeelf_destroy(jit_writeelf_t writeelf)
   404  {
   405  	int index;
   406  	if(!writeelf)
   407  	{
   408  		return;
   409  	}
   410  	for(index = 0; index < writeelf->num_sections; ++index)
   411  	{
   412  		jit_free(writeelf->sections[index].data);
   413  	}
   414  	jit_free(writeelf->sections);
   415  	jit_free(writeelf);
   416  }
   417  
   418  /*@
   419   * @deftypefun int jit_writeelf_write (jit_writeelf_t @var{writeelf}, const char *@var{filename})
   420   * Write a fully-built ELF binary to @var{filename}.  Returns zero
   421   * if an error occurred (reason in @code{errno}).
   422   * @end deftypefun
   423  @*/
   424  int jit_writeelf_write(jit_writeelf_t writeelf, const char *filename)
   425  {
   426  	/* TODO */
   427  	return 1;
   428  }
   429  
   430  /*@
   431   * @deftypefun int jit_writeelf_add_function (jit_writeelf_t @var{writeelf}, jit_function_t @var{func}, const char *@var{name})
   432   * Write the code for @var{func} to the ELF binary represented by
   433   * @var{writeelf}.  The function must already be compiled, and its
   434   * context must have the @code{JIT_OPTION_PRE_COMPILE} option set
   435   * to a non-zero value.  Returns zero if out of memory or the
   436   * parameters are invalid.
   437   * @end deftypefun
   438  @*/
   439  int jit_writeelf_add_function
   440  	(jit_writeelf_t writeelf, jit_function_t func, const char *name)
   441  {
   442  	/* TODO */
   443  	return 1;
   444  }
   445  
   446  /*@
   447   * @deftypefun int jit_writeelf_add_needed (jit_writeelf_t @var{writeelf}, const char *@var{library_name})
   448   * Add @var{library_name} to the list of dependent libraries that are needed
   449   * when the ELF binary is reloaded.  If @var{library_name} is already on
   450   * the list, then this request will be silently ignored.  Returns
   451   * zero if out of memory or the parameters are invalid.
   452   * @end deftypefun
   453  @*/
   454  int jit_writeelf_add_needed(jit_writeelf_t writeelf, const char *library_name)
   455  {
   456  	jit_section_t section;
   457  	Elf_Dyn *dyn;
   458  	unsigned int num_dyn;
   459  	Elf_Word name_index;
   460  	if(!writeelf || !library_name)
   461  	{
   462  		return 0;
   463  	}
   464  	section = get_section(writeelf, ".dynamic", SHT_DYNAMIC,
   465  						  SHF_WRITE | SHF_ALLOC,
   466  						  sizeof(Elf_Dyn), sizeof(Elf_Dyn));
   467  	if(!section)
   468  	{
   469  		return 0;
   470  	}
   471  	dyn = (Elf_Dyn *)(section->data);
   472  	num_dyn = section->data_len / sizeof(Elf_Dyn);
   473  	while(num_dyn > 0)
   474  	{
   475  		if(dyn->d_tag == DT_NEEDED &&
   476  		   !jit_strcmp(get_dyn_string(writeelf, (Elf_Word)(dyn->d_un.d_ptr)),
   477  		   			   library_name))
   478  		{
   479  			return 1;
   480  		}
   481  		++dyn;
   482  		--num_dyn;
   483  	}
   484  	name_index = add_dyn_string(writeelf, library_name);
   485  	if(!name_index)
   486  	{
   487  		return 0;
   488  	}
   489  	if(!add_dyn_info(writeelf, DT_NEEDED, (Elf_Addr)name_index, 0))
   490  	{
   491  		return 0;
   492  	}
   493  	return 1;
   494  }
   495  
   496  /*@
   497   * @deftypefun int jit_writeelf_write_section (jit_writeelf_t @var{writeelf}, const char *@var{name}, jit_int @var{type}, const void *@var{buf}, unsigned int @var{len}, int @var{discardable})
   498   * Write auxillary data to a section called @var{name}.  If @var{type}
   499   * is not zero, then it indicates an ELF section type.  This is used
   500   * by virtual machines to store auxillary data that can be retrieved
   501   * later using @code{jit_readelf_get_section}.  If the section already
   502   * contains data, then this will append the new data.  If @var{discardable}
   503   * is non-zero, then it is OK for this section to be discarded when the
   504   * ELF binary is stripped.  Returns zero if out of memory or the
   505   * parameters are invalid.
   506   * @end deftypefun
   507  @*/
   508  int jit_writeelf_write_section
   509  	(jit_writeelf_t writeelf, const char *name, jit_int type,
   510  	 const void *buf, unsigned int len, int discardable)
   511  {
   512  	jit_section_t section;
   513  	if(!writeelf || !name)
   514  	{
   515  		return 0;
   516  	}
   517  	if(!type)
   518  	{
   519  		/* Application-specific section type, for storing unspecified data */
   520  		type = (jit_int)(SHT_LOUSER + 0x1234);
   521  	}
   522  	if(discardable)
   523  	{
   524  		section = get_section(writeelf, name, type, 0, 1, 1);
   525  	}
   526  	else
   527  	{
   528  		section = get_section(writeelf, name, type, SHF_ALLOC, 1, 1);
   529  	}
   530  	if(!section)
   531  	{
   532  		return 0;
   533  	}
   534  	if(len > 0)
   535  	{
   536  		return add_to_section(section, buf, len);;
   537  	}
   538  	else
   539  	{
   540  		return 1;
   541  	}
   542  }