libnxflat_init.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /****************************************************************************
  2. * binfmt/libnxflat/libnxflat_init.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <sys/stat.h>
  25. #include <stdint.h>
  26. #include <string.h>
  27. #include <fcntl.h>
  28. #include <nxflat.h>
  29. #include <debug.h>
  30. #include <errno.h>
  31. #include <arpa/inet.h>
  32. #include <nuttx/fs/fs.h>
  33. #include <nuttx/binfmt/nxflat.h>
  34. /****************************************************************************
  35. * Pre-processor Definitions
  36. ****************************************************************************/
  37. /* CONFIG_DEBUG_FEATURES, CONFIG_DEBUG_INFO, and CONFIG_DEBUG_BINFMT have to
  38. * be defined or CONFIG_NXFLAT_DUMPBUFFER does nothing.
  39. */
  40. #if !defined(CONFIG_DEBUG_INFO) || !defined (CONFIG_DEBUG_BINFMT)
  41. # undef CONFIG_NXFLAT_DUMPBUFFER
  42. #endif
  43. #ifdef CONFIG_NXFLAT_DUMPBUFFER
  44. # define nxflat_dumpbuffer(m,b,n) binfodumpbuffer(m,b,n)
  45. #else
  46. # define nxflat_dumpbuffer(m,b,n)
  47. #endif
  48. /****************************************************************************
  49. * Private Constant Data
  50. ****************************************************************************/
  51. /****************************************************************************
  52. * Private Functions
  53. ****************************************************************************/
  54. /****************************************************************************
  55. * Public Functions
  56. ****************************************************************************/
  57. /****************************************************************************
  58. * Name: nxflat_init
  59. *
  60. * Description:
  61. * This function is called to configure the library to process an NXFLAT
  62. * program binary.
  63. *
  64. * Returned Value:
  65. * 0 (OK) is returned on success and a negated errno is returned on
  66. * failure.
  67. *
  68. ****************************************************************************/
  69. int nxflat_init(const char *filename, struct nxflat_loadinfo_s *loadinfo)
  70. {
  71. uint32_t datastart;
  72. uint32_t dataend;
  73. uint32_t bssend;
  74. int ret;
  75. binfo("filename: %s loadinfo: %p\n", filename, loadinfo);
  76. /* Clear the load info structure */
  77. memset(loadinfo, 0, sizeof(struct nxflat_loadinfo_s));
  78. /* Open the binary file */
  79. loadinfo->filfd = nx_open(filename, O_RDONLY);
  80. if (loadinfo->filfd < 0)
  81. {
  82. ret = loadinfo->filfd;
  83. berr("ERROR: Failed to open NXFLAT binary %s: %d\n", filename, ret);
  84. return ret;
  85. }
  86. /* Read the NXFLAT header from offset 0 */
  87. ret = nxflat_read(loadinfo, (FAR char *)&loadinfo->header,
  88. sizeof(struct nxflat_hdr_s), 0);
  89. if (ret < 0)
  90. {
  91. berr("ERROR: Failed to read NXFLAT header: %d\n", ret);
  92. nx_close(loadinfo->filfd);
  93. return ret;
  94. }
  95. nxflat_dumpbuffer("NXFLAT header", (FAR const uint8_t *)&loadinfo->header,
  96. sizeof(struct nxflat_hdr_s));
  97. /* Verify the NXFLAT header */
  98. if (nxflat_verifyheader(&loadinfo->header) != 0)
  99. {
  100. /* This is not an error because we will be called to attempt loading
  101. * EVERY binary. Returning -ENOEXEC simply informs the system that
  102. * the file is not an NXFLAT file. Besides, if there is something
  103. * worth complaining about, nnxflat_verifyheader() has already
  104. * done so.
  105. */
  106. berr("ERROR: Bad NXFLAT header\n");
  107. nx_close(loadinfo->filfd);
  108. return -ENOEXEC;
  109. }
  110. /* Save all of the input values in the loadinfo structure
  111. * and extract some additional information from the xflat
  112. * header. Note that the information in the xflat header is in
  113. * network order.
  114. */
  115. datastart = ntohl(loadinfo->header.h_datastart);
  116. dataend = ntohl(loadinfo->header.h_dataend);
  117. bssend = ntohl(loadinfo->header.h_bssend);
  118. /* And put this information into the loadinfo structure as well.
  119. *
  120. * Note that:
  121. *
  122. * isize = the address range from 0 up to datastart.
  123. * datasize = the address range from datastart up to dataend
  124. * bsssize = the address range from dataend up to bssend.
  125. */
  126. loadinfo->entryoffs = ntohl(loadinfo->header.h_entry);
  127. loadinfo->isize = datastart;
  128. loadinfo->datasize = dataend - datastart;
  129. loadinfo->bsssize = bssend - dataend;
  130. loadinfo->stacksize = ntohl(loadinfo->header.h_stacksize);
  131. /* This is the initial dspace size. We'll re-calculate this later
  132. * after the memory has been allocated.
  133. */
  134. loadinfo->dsize = bssend - datastart;
  135. /* Get the offset to the start of the relocations (we'll relocate
  136. * this later).
  137. */
  138. loadinfo->relocstart = ntohl(loadinfo->header.h_relocstart);
  139. loadinfo->reloccount = ntohs(loadinfo->header.h_reloccount);
  140. return 0;
  141. }