libelf_addrenv.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /****************************************************************************
  2. * binfmt/libelf/libelf_addrenv.c
  3. *
  4. * Copyright (C) 2012 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <errno.h>
  40. #include <debug.h>
  41. #include <nuttx/arch.h>
  42. #include <nuttx/kmalloc.h>
  43. #include "libelf.h"
  44. /****************************************************************************
  45. * Pre-processor Definitions
  46. ****************************************************************************/
  47. /****************************************************************************
  48. * Private Constant Data
  49. ****************************************************************************/
  50. /****************************************************************************
  51. * Private Functions
  52. ****************************************************************************/
  53. /****************************************************************************
  54. * Public Functions
  55. ****************************************************************************/
  56. /****************************************************************************
  57. * Name: elf_addrenv_alloc
  58. *
  59. * Description:
  60. * Allocate memory for the ELF image (textalloc and dataalloc). If
  61. * CONFIG_ARCH_ADDRENV=n, textalloc will be allocated using kmm_zalloc()
  62. * and dataalloc will be a offset from textalloc. If
  63. * CONFIG_ARCH_ADDRENV=y, then textalloc and dataalloc will be allocated
  64. * using up_addrenv_create(). In either case, there will be a unique
  65. * instance of textalloc and dataalloc (and stack) for each instance of a
  66. * process.
  67. *
  68. * Input Parameters:
  69. * loadinfo - Load state information
  70. * textsize - The size (in bytes) of the .text address environment needed
  71. * for the ELF image (read/execute).
  72. * datasize - The size (in bytes) of the .bss/.data address environment
  73. * needed for the ELF image (read/write).
  74. * heapsize - The initial size (in bytes) of the heap address environment
  75. * needed by the task. This region may be read/write only.
  76. *
  77. * Returned Value:
  78. * Zero (OK) on success; a negated errno value on failure.
  79. *
  80. ****************************************************************************/
  81. int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
  82. size_t datasize, size_t heapsize)
  83. {
  84. #ifdef CONFIG_ARCH_ADDRENV
  85. FAR void *vtext;
  86. FAR void *vdata;
  87. int ret;
  88. /* Create an address environment for the new ELF task */
  89. ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv);
  90. if (ret < 0)
  91. {
  92. berr("ERROR: up_addrenv_create failed: %d\n", ret);
  93. return ret;
  94. }
  95. /* Get the virtual address associated with the start of the address
  96. * environment. This is the base address that we will need to use to
  97. * access the ELF image (but only if the address environment has been
  98. * selected.
  99. */
  100. ret = up_addrenv_vtext(&loadinfo->addrenv, &vtext);
  101. if (ret < 0)
  102. {
  103. berr("ERROR: up_addrenv_vtext failed: %d\n", ret);
  104. return ret;
  105. }
  106. ret = up_addrenv_vdata(&loadinfo->addrenv, textsize, &vdata);
  107. if (ret < 0)
  108. {
  109. berr("ERROR: up_addrenv_vdata failed: %d\n", ret);
  110. return ret;
  111. }
  112. loadinfo->textalloc = (uintptr_t)vtext;
  113. loadinfo->dataalloc = (uintptr_t)vdata;
  114. return OK;
  115. #else
  116. /* Allocate memory to hold the ELF image */
  117. loadinfo->textalloc = (uintptr_t)kumm_malloc(textsize + datasize);
  118. if (!loadinfo->textalloc)
  119. {
  120. return -ENOMEM;
  121. }
  122. loadinfo->dataalloc = loadinfo->textalloc + textsize;
  123. return OK;
  124. #endif
  125. }
  126. /****************************************************************************
  127. * Name: elf_addrenv_free
  128. *
  129. * Description:
  130. * Release the address environment previously created by
  131. * elf_addrenv_alloc(). This function is called only under certain error
  132. * conditions after the module has been loaded but not yet started.
  133. * After the module has been started, the address environment will
  134. * automatically be freed when the module exits.
  135. *
  136. * Input Parameters:
  137. * loadinfo - Load state information
  138. *
  139. * Returned Value:
  140. * None.
  141. *
  142. ****************************************************************************/
  143. void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
  144. {
  145. #ifdef CONFIG_ARCH_ADDRENV
  146. int ret;
  147. /* Free the address environment */
  148. ret = up_addrenv_destroy(&loadinfo->addrenv);
  149. if (ret < 0)
  150. {
  151. berr("ERROR: up_addrenv_destroy failed: %d\n", ret);
  152. }
  153. #else
  154. /* If there is an allocation for the ELF image, free it */
  155. if (loadinfo->textalloc != 0)
  156. {
  157. kumm_free((FAR void *)loadinfo->textalloc);
  158. }
  159. #endif
  160. /* Clear out all indications of the allocated address environment */
  161. loadinfo->textalloc = 0;
  162. loadinfo->dataalloc = 0;
  163. loadinfo->textsize = 0;
  164. loadinfo->datasize = 0;
  165. }