loadElfLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:159k
源码类别:

VxWorks

开发平台:

C/C++

  1. *
  2. * loadElfModuleIsOk - check the object module format
  3. *
  4. * This routine contains the heuristic required to determine if the object
  5. * file belongs to the OMF handled by this OMF reader, with care for the target
  6. * architecture.
  7. * It is the underlying routine for loadElfFmtCheck().
  8. *
  9. * RETURNS: TRUE or FALSE if something prevent the loader to handle the module.
  10. */
  11. LOCAL BOOL loadElfModuleIsOk
  12.     (
  13.     Elf32_Ehdr * pHdr /* ELF module header */
  14.     )
  15.     {
  16.     BOOL        moduleIsForTarget = FALSE;      /* TRUE if for target*/
  17.     UINT16      targetMachine;           /* target of module */
  18.     BOOL dummy = FALSE;
  19.     /* Check that the module begins with "x7fELF" */
  20.     if (strncmp ((char *) pHdr->e_ident, (char *) ELFMAG, SELFMAG) != 0)
  21. {
  22. printErr ("Unknown object module format n");
  23. return FALSE;
  24. }
  25.     /*
  26.      * Get the target machine identification and checks that the object
  27.      * module is appropriate for the architecture.
  28.      * Note that the switch statement below should disappear when all
  29.      * reloction units will offer an initialization routine.
  30.      */
  31.     targetMachine = pHdr->e_machine;
  32.     if (pElfModuleVerifyRtn != NULL)
  33. {
  34. #ifdef INCLUDE_SDA
  35. moduleIsForTarget = pElfModuleVerifyRtn (targetMachine, &sdaIsRequired);
  36. #else
  37. moduleIsForTarget = pElfModuleVerifyRtn (targetMachine, &dummy);
  38. #endif /* INCLUDE_SDA */
  39. }
  40.     else if (targetMachine == EM_ARCH_MACHINE)
  41. {
  42. moduleIsForTarget = TRUE;
  43. #if (EM_ARCH_MACHINE == EM_PPC) && defined(INCLUDE_SDA)
  44. sdaIsRequired = TRUE;
  45. #endif /* INCLUDE_SDA */
  46. }
  47.     return moduleIsForTarget;
  48.     }
  49. /******************************************************************************
  50. *
  51. * loadElfMdlHdrCheck - check the module header
  52. *
  53. * This routine checks the validity of a file header structure.
  54. *
  55. * RETURNS : OK, or ERROR if the header is not correct.
  56. */
  57. LOCAL STATUS loadElfMdlHdrCheck
  58.     (
  59.     Elf32_Ehdr * pHdr /* ptr on header structure to check */
  60.     )
  61.     {
  62.     if (pHdr->e_ehsize != sizeof (*pHdr))
  63. {
  64. printErr ("Incorrect ELF header size: %dn", pHdr->e_ehsize);
  65. return (ERROR);
  66. }
  67.     if ((pHdr->e_type != ET_REL) && (pHdr->e_type != ET_EXEC))
  68. {
  69. printErr ("Incorrect module type: %dn", pHdr->e_type);
  70. return (ERROR);
  71. }
  72.     if ((pHdr->e_type == ET_EXEC) && (pHdr->e_phnum == 0))
  73. {
  74. printErr ("No program header table in executable module.n");
  75. return (ERROR);
  76. }
  77.     if ((pHdr->e_phnum != 0) && (pHdr->e_phoff == 0))
  78. {
  79. printErr ("Null offset to program header table.n");
  80. return (ERROR);
  81. }
  82.     if ((pHdr->e_type == ET_EXEC) && (pHdr->e_phentsize != sizeof (Elf32_Phdr)))
  83. {
  84. printErr ("Incorrect program header size: %dn", pHdr->e_phentsize);
  85. return (ERROR);
  86. }
  87.     if (pHdr->e_shentsize != sizeof (Elf32_Shdr))
  88. {
  89. printErr ("Incorrect section header size: %dn", pHdr->e_shentsize);
  90. return (ERROR);
  91. }
  92.     if ((pHdr->e_shnum != 0) && (pHdr->e_shoff == 0))
  93. {
  94. printErr ("Null offset to section header table.n");
  95. return (ERROR);
  96. }
  97.     return (OK);
  98.     }
  99. /******************************************************************************
  100. *
  101. * loadElfMdlHdrRd - "Read in" the module header
  102. *
  103. * This routine fills a file header structure with information from the object
  104. * file.
  105. *
  106. * RETURNS : OK, or ERROR if the header is not correct.
  107. */
  108. LOCAL STATUS loadElfMdlHdrRd
  109.     (
  110.     int  fd, /* file to read in */
  111.     Elf32_Ehdr * pHdr /* ptr on header structure to fill */
  112.     )
  113.     {
  114.     ioctl(fd, FIOSEEK, 0);
  115.     if (fioRead (fd, (char *) pHdr, sizeof (Elf32_Ehdr)) 
  116. != sizeof (Elf32_Ehdr))
  117.      return (ERROR);
  118.     if (loadElfMdlHdrCheck (pHdr) != OK)
  119. return (ERROR);
  120.     return (OK);
  121.     }
  122. /******************************************************************************
  123. *
  124. * loadElfProgHdrCheck - check a program header
  125. *
  126. * This routine checks the validity of a program header structure.
  127. *
  128. * RETURNS : OK, or ERROR if the header is not correct.
  129. */
  130. LOCAL STATUS loadElfProgHdrCheck
  131.     (
  132.     Elf32_Phdr * pProgHdr, /* pointer to a program header */
  133.     int progHdrNum /* number of the program header */
  134.     )
  135.     {
  136.     if (!CHECK_2_ALIGN (pProgHdr->p_align)) /* align must be power of 2 */
  137. {
  138.         errnoSet (S_loadElfLib_HDR_ERROR);
  139. return (ERROR);
  140. }
  141.     return (OK);
  142.     }
  143. /******************************************************************************
  144. *
  145. * loadElfProgHdrTblRd - "Read in" the program header table
  146. *
  147. * This routine fills a program header structure with information from the
  148. * object file.
  149. * Each program header in the program header table is processed in turn.
  150. *
  151. * RETURNS : OK, or ERROR if a program header is not correct.
  152. */
  153. LOCAL STATUS loadElfProgHdrTblRd
  154.     (
  155.     int           fd,            /* file to read in */
  156.     int           posProgHdrField,/* positon of first program header */
  157.     Elf32_Phdr * pProgHdrTbl, /* pointer to program header table */
  158.     int                 progHdrNumber   /* number of header in table */
  159.     )
  160.     {
  161.     int progHdrIndex; /* loop counter */
  162.     Elf32_Phdr * pProgHdr; /* pointer to a program header */
  163.     /* Read all the programs header */
  164.     ioctl (fd, FIOSEEK, posProgHdrField);
  165.     if (fioRead (fd, (char *) pProgHdrTbl, progHdrNumber * sizeof (Elf32_Phdr)) 
  166. != progHdrNumber * sizeof (Elf32_Phdr))
  167.      {
  168.      errnoSet (S_loadElfLib_HDR_ERROR);
  169.      return (ERROR);
  170.      }
  171.     /* loop thru all the program headers */
  172.     for (progHdrIndex = 0; progHdrIndex < progHdrNumber; progHdrIndex++)
  173. {
  174. pProgHdr = pProgHdrTbl + progHdrIndex;
  175.         /* Check the program header */
  176. if (loadElfProgHdrCheck (pProgHdr, progHdrIndex) != OK)
  177.     return (ERROR);
  178. }
  179.     return (OK);
  180.     }
  181. /******************************************************************************
  182. *
  183. * loadElfScnHdrCheck - check a section header
  184. *
  185. * This routine checks the validity of a section header structure.
  186. *
  187. * RETURNS : OK, or ERROR if the header is not correct.
  188. */
  189. LOCAL STATUS loadElfScnHdrCheck
  190.     (
  191.     Elf32_Shdr * pScnHdr, /* pointer to a section header */
  192.     int scnHdrNum /* number of the section header */
  193.     )
  194.     {
  195.     if (!CHECK_2_ALIGN (pScnHdr->sh_addralign)) /* align must be power of 2 */
  196. {
  197.         errnoSet (S_loadElfLib_SHDR_READ);
  198. return (ERROR);
  199. }
  200.     return (OK);
  201.     }
  202. /******************************************************************************
  203. *
  204. * loadElfScnHdrIdxDispatch - dispatch the section header index
  205. *
  206. * This routine dispatches the section header into various "databases" depending
  207. * on the section type. Only the section header index in the section header
  208. * table is registred in the "databases".
  209. *
  210. * RETURNS : OK, or ERROR
  211. */
  212. LOCAL STATUS loadElfScnHdrIdxDispatch
  213.     (
  214.     Elf32_Shdr * pScnHdrTbl, /* pointer to section header table */
  215.     int  scnHdrIdx, /* index of current section header */
  216.     IDX_TBLS   * pIndexTables /* pointer to section index tables */
  217.     )
  218.     {
  219.     Elf32_Shdr * pScnHdr; /* pointer to a section header */
  220.     Elf32_Shdr * pAllocScnHdr; /* ptr to header of allocatable scn */
  221.     static int  loadSections = 0; /* counter of text, data, literal or */
  222. /* bss section headers */
  223.     static int  symTableSections = 0; /* counter of symbol table section */
  224. /* headers */
  225.     static int  relocSections = 0; /* counter of relocation information */
  226. /* section headers */
  227.     static int  strTableSections = 0; /* counter of string table section */
  228. /* headers */
  229.     /* Reinitialization of counters */
  230.     if (pScnHdrTbl == NULL)
  231. {
  232. loadSections = 0;
  233. symTableSections = 0;
  234. relocSections = 0;
  235. strTableSections = 0;
  236. return (OK);
  237. }
  238.     /* Get current section header */
  239.     pScnHdr = pScnHdrTbl + scnHdrIdx;
  240.     /* Dispatch the section headers index among the "databases" */
  241.     switch (pScnHdr->sh_type)
  242.         {
  243.         case (SHT_PROGBITS): /* text, data, literal sections */
  244.         case (SHT_NOBITS): /* bss sections */
  245.     /*
  246.      * Just consider the sections that will be allocated in the
  247.      * target memory. Thus debug sections are discarded.
  248.      */
  249.     if (pScnHdr->sh_flags & SHF_ALLOC)
  250.         pIndexTables->pLoadScnHdrIdxs [loadSections++] = scnHdrIdx;
  251.     break;
  252.         case (SHT_SYMTAB): /* symbol table sections */
  253.     pIndexTables->pSymTabScnHdrIdxs [symTableSections++] = scnHdrIdx;
  254.     break;
  255.         case (SHT_DYNSYM): /* minimal symbol table */
  256.     printErr ("Section type SHT_DYNSYM not supported.n");
  257.     break;
  258.         case (SHT_REL): /* relocation info sections */
  259.         case (SHT_RELA): /* relocation with addend info section*/
  260.     /*
  261.      * We only keep the relocation sections related to an
  262.      * allocatable section. Relocation sections related to debug
  263.      * sections are then discarded.
  264.      */
  265.     pAllocScnHdr = pScnHdrTbl + pScnHdr->sh_info;
  266.     if ((pAllocScnHdr->sh_flags & SHF_ALLOC) &&
  267.         (pAllocScnHdr->sh_type == SHT_PROGBITS))
  268.         pIndexTables->pRelScnHdrIdxs [relocSections++] = scnHdrIdx;
  269.     break;
  270.         case (SHT_STRTAB): /* string table sections */
  271.     pIndexTables->pStrTabScnHdrIdxs [strTableSections++] = scnHdrIdx;
  272.     break;
  273.         }
  274.     return (OK);
  275.     }
  276. /******************************************************************************
  277. *
  278. * loadElfScnHdrRd - "Read in" the sections header
  279. *
  280. * This routine fills a section header structure with information from the
  281. * object file in memory.
  282. * Each section header in the section header table is processed in turn.
  283. *
  284. * RETURNS : OK or ERROR if a section header is not correct.
  285. */
  286. LOCAL STATUS loadElfScnHdrRd
  287.     (
  288.     int  fd, /* file to read in */
  289.     int   posScnHdrField,        /* positon of first section header */
  290.     Elf32_Shdr * pScnHdrTbl, /* section header table */
  291.     int          sectionNumber,         /* number of sections */
  292.     IDX_TBLS   * pIndexTables /* pointer to section index tables */
  293.     )
  294.     {
  295.     int  scnHdrIdx; /* loop counter */
  296.     Elf32_Shdr * pScnHdr; /* pointer to a section header */
  297.     /* Initialization */
  298.     loadElfScnHdrIdxDispatch (NULL, 0, NULL);
  299.     /* Read all the sections header */
  300.     ioctl (fd, FIOSEEK, posScnHdrField);
  301.     if ((fioRead (fd, (char *) pScnHdrTbl, sectionNumber * sizeof(Elf32_Shdr))) 
  302. != sectionNumber * sizeof(Elf32_Shdr))
  303.       {
  304.             errnoSet (S_loadElfLib_SHDR_READ);
  305.     return (ERROR);
  306.     }
  307.     /* loop thru all the sections headers */
  308.     for (scnHdrIdx = 0; scnHdrIdx < sectionNumber; scnHdrIdx++)
  309. {
  310. pScnHdr = pScnHdrTbl + scnHdrIdx;
  311.         /* Check the section header */
  312. if (loadElfScnHdrCheck (pScnHdr, scnHdrIdx) != OK)
  313.     return (ERROR);
  314. /* Record the indexes of the headers of various section types */
  315. loadElfScnHdrIdxDispatch (pScnHdrTbl, scnHdrIdx, pIndexTables);
  316.         }
  317.     return (OK);
  318.     }
  319. /*******************************************************************************
  320. *
  321. * loadElfSegSizeGet - determine segment sizes from section headers
  322. *
  323. * This function fills in the size fields in the SEG_INFO structure when the
  324. * module is relocatable.
  325. *
  326. * RETURNS : N/A
  327. */
  328. LOCAL void loadElfSegSizeGet
  329.     (
  330.     char *       pScnStrTbl,         /* ptr to section name string  table */
  331.     UINT32 *  pLoadScnHdrIdxs, /* index of loadable section hdrs */
  332.     Elf32_Shdr * pScnHdrTbl, /* pointer to section header table */
  333.     SEG_INFO *  pSeg /* section addresses and sizes */
  334.     )
  335.     {
  336.     int index; /* loop counter */
  337.     int                 nbytes;         /* bytes required for alignment */
  338.     Elf32_Shdr * pScnHdr; /* pointer to a section header */
  339.     int textAlign; /* Alignment for text segment */
  340.     int dataAlign; /* Alignment for data segment */
  341.     int bssAlign; /* Alignment for bss segment */
  342.     SDA_SCN_TYPE        sdaScnVal;      /* type of SDA section */
  343.     SDA_INFO *          pSda = NULL;    /* SDA section addresses and sizes */
  344.     pSeg->sizeText = 0;
  345.     pSeg->sizeData = 0;
  346.     pSeg->sizeBss = 0;
  347. #ifdef INCLUDE_SDA
  348.     /* ELF modules for PowerPC may have additional specific sections */
  349.     if (pSeg->pAdnlInfo != NULL)
  350.         {
  351.         pSda = (SDA_INFO *) pSeg->pAdnlInfo;
  352.         pSda->sizeSdata = 0;
  353.         pSda->sizeSbss = 0;
  354.         pSda->sizeSdata2 = 0;
  355.         pSda->sizeSbss2 = 0;
  356.         }
  357. #endif /* INCLUDE_SDA */
  358.     /* Set minimum alignments for segments */
  359.     textAlign = _ALLOC_ALIGN_SIZE;
  360.     dataAlign = _ALLOC_ALIGN_SIZE;
  361.     bssAlign  = _ALLOC_ALIGN_SIZE;
  362.     /* loop thru all loadable sections */
  363.     for (index = 0; pLoadScnHdrIdxs[index] != 0; index++)
  364. {
  365. pScnHdr = pScnHdrTbl + pLoadScnHdrIdxs [index];
  366.         /* Determine if section is sdata/sbss, sdata2/sbss2 or anything else */
  367. #ifdef INCLUDE_SDA
  368.         if (pSda != NULL)
  369.             sdaScnVal = loadElfSdaScnDetermine (pScnStrTbl, pScnHdr, NULL);
  370.         else
  371. #endif /* INCLUDE_SDA */
  372.             sdaScnVal = NOT_SDA_SCN;
  373.         /*
  374.  * To follow the three-segment model, all sections of same type are
  375.  * loaded following each others within the area allocated for the
  376.  * segment. But, sections must be loaded at addresses that fit with
  377.  * the alignment requested or, by default, with the target
  378.  * architecture's alignment requirement. So, the segment size is the
  379.  * total size of the sections integrated in this segment plus the
  380.  * number of bytes that create the required offset to align the next
  381.  * sections :
  382.  * 
  383.  *     +-------------+ <- segment base address (aligned thanks to the
  384.  *     |:::::::::::::|    memory manager). This is also the load 
  385.  *     |::::Text:::::|    address of the first section.
  386.  *     |:Section:1:::|
  387.  *     |:::::::::::::|
  388.  *     |:::::::::::::|
  389.  *     +-------------+ <- end of first section.
  390.  *     |/////////////| <- offset needed to reach next aligned address.
  391.  *     +-------------+ <- aligned load address of next section within
  392.  *     |:::::::::::::|    the segment.
  393.  *     |:::::::::::::|
  394.  *     |:::::::::::::|
  395.  *     |::::Text:::::|
  396.  *     |:Section:2:::|
  397.  *     |:::::::::::::|
  398.  *     |:::::::::::::|
  399.  *     |:::::::::::::|
  400.  *     |:::::::::::::|
  401.  *     +-------------+
  402.  *     |             |
  403.  *
  404.  * The principle here is to determine, for a given section type (text,
  405.  * data or bss), how much padding bytes should be added to the previous
  406.  * section in order to be sure that the current section will be
  407.  * correctly aligned. This means that the first section of each type is
  408.  * considered as "de facto" aligned. Note that this assumption is
  409.  * correct only if each segment is allocated separately (since
  410.  * tgtMemMalloc() returns an aligned address). If however only one
  411.  * memory area is allocated for the three segments (as do
  412.  * loadSegmentsAllocate()), an other round of alignment computation
  413.  * must be done between the three segments.
  414.  */
  415. switch (pScnHdr->sh_type)
  416.     {
  417.     case SHT_PROGBITS: /* data and text sections */
  418. /* 
  419.  * Previously, if the SHF_ALLOC and SHF_WRITE flags were set,
  420.  * thesection was determined to be a data section. Hence text
  421.  * sections were expected to be read only. This logic causes
  422.  * problems for fully linked files such as the VxWorks image
  423.  * if the linker's -N option is used. This option forces the
  424.  * toolchain to disregard the ELF standard and generate text
  425.  * sections with the SHF_WRITE flag set (among other things).
  426.  * Let's be a bit more flexible and check the absence of the
  427.  * SHF_EXECINSTR flag to determine a data section...
  428.  */
  429. if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  430.     (pScnHdr->sh_flags & SHF_WRITE) &&
  431.     !(pScnHdr->sh_flags & SHF_EXECINSTR))
  432.     {
  433.                     /*
  434.                      * This is data section. Note that SDA data sections are
  435.                      * stored in dedicated areas in the target's memory. They
  436.                      * are then handled separately.
  437.                      *
  438.                      * XXX PAD this is not enough to differentiate data
  439.                      * sections from Global Offset Table sections.
  440.                      */
  441.                     switch (sdaScnVal)
  442.                         {
  443.                         case NOT_SDA_SCN:
  444.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  445.                                                      (void *) pSeg->sizeData);
  446.                             pSeg->sizeData += pScnHdr->sh_size + nbytes;
  447.     /* 
  448.      * Record segment alignment.  The alignment of 
  449.      * each segment should be the maximum of the 
  450.      * alignments required by all sections in the 
  451.      * segment, not just the alignment of the first 
  452.      * section.  
  453.      */
  454.     if (pScnHdr->sh_addralign > dataAlign)
  455. dataAlign = pScnHdr->sh_addralign;
  456.                             break;
  457.                         case SDA_SCN:
  458.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  459.                                                      (void *)pScnHdr->sh_size);
  460.                             pSda->sizeSdata = pScnHdr->sh_size + nbytes;
  461.                             break;
  462.                         case SDA2_SCN:
  463.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  464.                                                      (void *)pScnHdr->sh_size);
  465.                             pSda->sizeSdata2 = pScnHdr->sh_size + nbytes;
  466.                             break;
  467.                         }
  468.                     }
  469. else if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  470.  (pScnHdr->sh_flags & SHF_EXECINSTR))
  471.     {
  472.                     /*
  473.                      * This is a text section.
  474.                      *
  475.                      * XXX PAD this is not enough to differentiate text
  476.                      * sections from Procedure Linkage Table sections on
  477.                      * processors other than the PowerPC.
  478.                      */
  479.                     nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  480.                                              (void *) pSeg->sizeText);
  481.                     pSeg->sizeText += pScnHdr->sh_size + nbytes;
  482.     /* 
  483.      * Record segment alignment.  The alignment of each segment
  484.      * should be the maximum of the alignments required by all 
  485.      * sections in the segment, not just the alignment of the 
  486.      * first section.   
  487.      */
  488.     if (pScnHdr->sh_addralign > textAlign)
  489. textAlign = pScnHdr->sh_addralign;
  490.              
  491.     }
  492. else if (pScnHdr->sh_flags & SHF_ALLOC)
  493.     {
  494.                     if (sdaScnVal == SDA2_SCN)
  495.                         {
  496.                         /*
  497.                          * This is unfortunate but .sdata2 sections may be not
  498.                          * writable. How strange...
  499.                          */
  500.                         nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  501.                                                  (void *)pScnHdr->sh_size);
  502.                         pSda->sizeSdata2 = pScnHdr->sh_size + nbytes;
  503.                         }
  504.                     else
  505.                         {
  506.                         /*
  507.                          * This is a read only data section. Since these
  508.                          * sections hold constant data, their contents is
  509.                          * considered as "text" by the loader (see
  510.                          * loadElfScnRd()). So, the size of the read only data
  511.                          * sections is added to the size of the text sections.
  512.                          */
  513.                         nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  514.                                                  (void *) pSeg->sizeText);
  515.                         pSeg->sizeText += pScnHdr->sh_size + nbytes;
  516. /* 
  517.  * Record segment alignment.  The alignment of each 
  518.  * segment should be the maximum of the alignments 
  519.  * required by all sections in the segment, not just 
  520.  * the alignment of the first section. 
  521.  */
  522. if (pScnHdr->sh_addralign > textAlign)
  523.     textAlign = pScnHdr->sh_addralign;
  524.                         }
  525.     }
  526. break;
  527.     case SHT_NOBITS: /* bss sections */
  528. if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  529.     (pScnHdr->sh_flags & SHF_WRITE))
  530.     {
  531.                     /*
  532.                      * This is bss section. Note that SDA bss sections are
  533.                      * stored in dedicated areas in the target's memory. They
  534.                      * are then handled separately.
  535.                      *
  536.                      * XXX PAD this is not enough to differentiate bss
  537.                      * sections from Procedure Linkage Table sections on
  538.                      * PowerPC processors.
  539.                      */
  540.                     switch (sdaScnVal)
  541.                         {
  542.                         case NOT_SDA_SCN:
  543.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  544.                                                      (void *) pSeg->sizeBss);
  545.                             pSeg->sizeBss += pScnHdr->sh_size + nbytes;
  546.     /* 
  547.      * Record segment alignment.  The alignment of 
  548.      * each segment should be the maximum of the 
  549.      * alignments required by all sections in the 
  550.      * segment, not just the alignment of the first 
  551.      * section.  
  552.      */
  553.     if (pScnHdr->sh_addralign > bssAlign)
  554. bssAlign = pScnHdr->sh_addralign;
  555.                             break;
  556.                         case SDA_SCN:
  557.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  558.                                                      (void *)pScnHdr->sh_size);
  559.                             pSda->sizeSbss = pScnHdr->sh_size + nbytes;
  560.                             break;
  561.                         case SDA2_SCN:
  562.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  563.                                                      (void *)pScnHdr->sh_size);
  564.                             pSda->sizeSbss2 = pScnHdr->sh_size + nbytes;
  565.                             break;
  566.                         }
  567.     }
  568. else
  569.     printErr ("Section SHT_NOBITS ignored (wrong flags).n");
  570. break;
  571.     }
  572. }
  573.     /* 
  574.      * SPR #21836: pSeg->flagsText, pSeg->flagsData, pSeg->flagsBss are used
  575.      * to save the alignment requirement for each segment. These fields of pSeg
  576.      * are only used on output, thus a temporary use is allowed.
  577.      */
  578.     
  579.     pSeg->flagsText = textAlign;
  580.     pSeg->flagsData = dataAlign;
  581.     pSeg->flagsBss  = bssAlign;
  582.     /* 
  583.      * Alloc alignment may be less than what is required by
  584.      * these particular sections.  Adjust sizes to allow for
  585.      * alignment after loadSegmentsAllocate().
  586.      */
  587.     if ((textAlign > _ALLOC_ALIGN_SIZE) && (pSeg->sizeText > 0))
  588.      pSeg->sizeText += textAlign - _ALLOC_ALIGN_SIZE;
  589.     if ((dataAlign > _ALLOC_ALIGN_SIZE) && (pSeg->sizeData > 0))
  590.         pSeg->sizeData += dataAlign - _ALLOC_ALIGN_SIZE;
  591.     if ((bssAlign > _ALLOC_ALIGN_SIZE) && (pSeg->sizeBss > 0))
  592.     pSeg->sizeBss += bssAlign - _ALLOC_ALIGN_SIZE;
  593.     /*
  594.      * If only one memory area is to be allocated for the three segments,
  595.      * takes care of the alignment between each three segments.
  596.      */
  597.     if ((pSeg->addrText == LD_NO_ADDRESS) &&
  598. (pSeg->addrData == LD_NO_ADDRESS) &&
  599. (pSeg->addrBss  == LD_NO_ADDRESS))
  600. {
  601. if (pSeg->sizeData > 0)
  602.             pSeg->sizeText += loadElfAlignGet (dataAlign,
  603.                                               (void *) pSeg->sizeText);
  604. if (pSeg->sizeBss > 0)
  605.     {
  606.     if (pSeg->sizeData > 0)
  607. pSeg->sizeData += loadElfAlignGet (bssAlign,
  608. (void *) (pSeg->sizeText + pSeg->sizeData));
  609.     else
  610. pSeg->sizeText += loadElfAlignGet (bssAlign,
  611. (void *) pSeg->sizeText);
  612.     }
  613. }
  614.     }
  615. /*******************************************************************************
  616. *
  617. * loadElfScnRd - "read" sections into the target memory
  618. *
  619. * This routine actually copies the sections contents into the target memory.
  620. * All the sections of the same type are coalesced so that we end up with a 
  621. * three segment model.
  622. *
  623. * RETURNS : OK or ERROR if a section couldn't be read in.
  624. */
  625. LOCAL STATUS loadElfScnRd
  626.     (
  627.     int  fd, /* file to read in */
  628.     char *       pScnStrTbl,         /* ptr to section name string  table */
  629.     UINT32 *  pLoadScnHdrIdxs, /* index of loadable section hdrs */
  630.     Elf32_Shdr * pScnHdrTbl, /* points to table of section headers */
  631.     SCN_ADRS_TBL sectionAdrsTbl, /* points to table of section addr */
  632.     SEG_INFO *  pSeg /* segments information */
  633.     )
  634.     {
  635.     int  index; /* loop counter */
  636.     Elf32_Shdr * pScnHdr; /* pointer to a section header */
  637.     SCN_ADRS *  pScnAddr; /* pointer to address of section */
  638.     void *  pTgtLoadAddr; /* target address to load data at */
  639.     INT32  scnSize; /* section size */
  640.     void *  pTextCurAddr; /* current addr where text is loaded */
  641.     void *  pDataCurAddr; /* current addr where data are loaded */
  642.     void *  pBssCurAddr; /* current addr where bss is "loaded" */
  643.     int          nbytes;                /* bytes required for alignment */
  644.     void *       pTgtSdaLoadAddr;       /* target address to load SDA scn at */
  645.     SDA_SCN_TYPE sdaScnVal;             /* type of SDA section */
  646.     SDA_INFO *   pSda = NULL;           /* SDA section addresses and sizes */
  647.     pTextCurAddr = pSeg->addrText;
  648.     pDataCurAddr = pSeg->addrData;
  649.     pBssCurAddr = pSeg->addrBss;
  650. #ifdef INCLUDE_SDA
  651.     /* ELF modules for PowerPC may have additional specific sections */
  652.     if (pSeg->pAdnlInfo != NULL)
  653.         pSda = (SDA_INFO *) pSeg->pAdnlInfo;
  654. #endif  /* INCLUDE_SDA */
  655.     /* Loop thru all loadable sections */
  656.     for (index = 0; pLoadScnHdrIdxs [index] != 0; index++)
  657. {
  658. pScnHdr = pScnHdrTbl + pLoadScnHdrIdxs [index];
  659. pScnAddr = sectionAdrsTbl + pLoadScnHdrIdxs [index];
  660.         pTgtLoadAddr = NULL;
  661. scnSize = pScnHdr->sh_size;
  662.         pTgtSdaLoadAddr = NULL;
  663.         /* Determine if section is sdata/sbss, sdata2/sbss2 or anything else */
  664. #ifdef INCLUDE_SDA
  665.         if (pSda != NULL)
  666.             sdaScnVal = loadElfSdaScnDetermine (pScnStrTbl, pScnHdr, NULL);
  667.         else
  668. #endif /* INCLUDE_SDA */
  669.             sdaScnVal = NOT_SDA_SCN;
  670. /*
  671.  * Only sections of type SHT_PROGBITS and SHT_NOBITS with flag
  672.  * SHF_ALLOC are considered here.
  673.  *
  674.  * About the section alignment, see explanations and diagram in
  675.  * loadElfSegSizeGet().
  676.  */
  677. switch (pScnHdr->sh_type)
  678.     {
  679.     case (SHT_PROGBITS): /* data and text sections */
  680. if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  681.     (pScnHdr->sh_flags & SHF_EXECINSTR))
  682.     {
  683.     /* This is text section */
  684.     pTgtLoadAddr = pTextCurAddr;
  685.                     nbytes = loadElfAlignGet(pScnHdr->sh_addralign,
  686. pTgtLoadAddr) ;
  687.                     pTgtLoadAddr = (UINT8 *)pTgtLoadAddr + nbytes;
  688.                     pTextCurAddr = (UINT8 *)pTgtLoadAddr + scnSize;
  689.     }
  690. else if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  691.  (pScnHdr->sh_flags & SHF_WRITE))
  692.     {
  693.     /* This is data section */
  694.                     switch (sdaScnVal)
  695.                         {
  696.                         case NOT_SDA_SCN:
  697.          pTgtLoadAddr = pDataCurAddr;
  698.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  699.                                                      pTgtLoadAddr);
  700.                             pTgtLoadAddr = (UINT8 *)pTgtLoadAddr + nbytes;
  701.                             pDataCurAddr = (UINT8 *)pTgtLoadAddr + scnSize;
  702.                             break;
  703.                         case SDA_SCN:
  704.                             pTgtSdaLoadAddr = pSda->pAddrSdata;
  705.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  706.                                                      pTgtSdaLoadAddr);
  707.                             pTgtSdaLoadAddr = (UINT8 *)pTgtSdaLoadAddr 
  708.      + nbytes ;
  709.                             break;
  710.                         case SDA2_SCN:
  711.                             pTgtSdaLoadAddr = pSda->pAddrSdata2;
  712.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  713.                                                      pTgtSdaLoadAddr);
  714.                             pTgtSdaLoadAddr = (UINT8 *)pTgtSdaLoadAddr 
  715.      + nbytes ;
  716.                             break;
  717.                         }
  718.                     }
  719.         else if (pScnHdr->sh_flags & SHF_ALLOC)
  720.     {
  721.                     if (sdaScnVal == SDA2_SCN)
  722.                         {
  723.                         /*
  724.                          * This is unfortunate but .sdata2 sections may be not
  725.                          * writable. How strange...
  726.                          */
  727.                         pTgtSdaLoadAddr = pSda->pAddrSdata2;
  728.                         nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  729.                                                  pTgtSdaLoadAddr);
  730.                         pTgtSdaLoadAddr = (UINT8 *)pTgtSdaLoadAddr + nbytes;
  731.                         }
  732.     else
  733. {
  734.      /*
  735.       * This is a read only data section. Since these sections
  736.       * hold constant data, their contents is considered as
  737.       * "text" by the loader. So, the size of the read only 
  738. * data sections is added to the size of the text 
  739. * sections.
  740.       */
  741.      pTgtLoadAddr = pTextCurAddr;
  742.                      nbytes = loadElfAlignGet(pScnHdr->sh_addralign,
  743.      pTgtLoadAddr) ;
  744.                      pTgtLoadAddr = (UINT8 *)pTgtLoadAddr + nbytes;
  745.                      pTextCurAddr = (UINT8 *)pTgtLoadAddr + scnSize;
  746.      }
  747.     }
  748. else
  749.     printErr("Section SHT_PROGBITS ignored (flags: %d).n",
  750.   pScnHdr->sh_flags);
  751.     break;
  752.     case (SHT_NOBITS): /* bss sections */
  753. if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  754.     (pScnHdr->sh_flags & SHF_WRITE))
  755.     {
  756.     /* 
  757.      * Bss sections. Such sections must not be downloaded since
  758.      * they don't actually exist in the object module. However
  759.      * for the relocation purpose, we need to know where they
  760.      * are located in the target memory.
  761.      */
  762.                     switch (sdaScnVal)
  763.                         {
  764.                         case NOT_SDA_SCN:
  765.          pTgtLoadAddr = pBssCurAddr;
  766.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  767.                                                      pTgtLoadAddr);
  768.                             pTgtLoadAddr = (UINT8 *)pTgtLoadAddr + nbytes;
  769.                             pBssCurAddr = (UINT8 *)pTgtLoadAddr + scnSize;
  770.                             break;
  771.                         case SDA_SCN:
  772.                             pTgtSdaLoadAddr = pSda->pAddrSbss;
  773.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  774.                                                      pTgtSdaLoadAddr);
  775.                             pTgtSdaLoadAddr = (UINT8 *)pTgtSdaLoadAddr 
  776. + nbytes ;
  777.                             break;
  778.                         case SDA2_SCN:
  779.                             pTgtSdaLoadAddr = pSda->pAddrSbss2;
  780.                             nbytes = loadElfAlignGet (pScnHdr->sh_addralign,
  781.                                                      pTgtSdaLoadAddr);
  782.                             pTgtSdaLoadAddr = (UINT8 *)pTgtSdaLoadAddr 
  783. + nbytes ;
  784.                             break;
  785.                         }
  786.     }
  787. else
  788.     printErr ("Section SHT_NOBITS ignored (flags: %d).n",
  789.    pScnHdr->sh_flags);
  790. break;
  791.     default: /* we should not get here */
  792. printErr("Section of type %d ignored.n",pScnHdr->sh_type);
  793. break;
  794.     }
  795.         /*
  796.  * Advance to position in file and copy the section into the target
  797.  * memory.
  798.          */
  799. if (pScnHdr->sh_type != SHT_NOBITS)
  800.     {
  801.     ioctl(fd, FIOSEEK, pScnHdr->sh_offset);
  802.             if (sdaScnVal == NOT_SDA_SCN)
  803.                 {
  804.      if (fioRead (fd, pTgtLoadAddr, scnSize) != scnSize)
  805.     {
  806.                  errnoSet (S_loadElfLib_SCN_READ);
  807.     return (ERROR);
  808.     }
  809.                 }
  810.             else
  811.                 {
  812.      if (fioRead (fd, pTgtSdaLoadAddr, scnSize) != scnSize)
  813.     {
  814.                  errnoSet (S_loadElfLib_SCN_READ);
  815.     return (ERROR);
  816.     }
  817.                 }
  818.     }
  819. /* record the load address of each section */
  820.         if (sdaScnVal == NOT_SDA_SCN)
  821.             *pScnAddr = pTgtLoadAddr;
  822.         else
  823.             *pScnAddr = pTgtSdaLoadAddr;
  824. }
  825.     return (OK);
  826.     }
  827. /*******************************************************************************
  828. *
  829. * loadElfSymEntryRd - "read in" a symbol entry
  830. *
  831. * This routine fills a symbol structure with information from the object
  832. * module in memory.
  833. *
  834. * RETURNS : the next symbol entry position in the module file.
  835. *
  836. */
  837. LOCAL int loadElfSymEntryRd
  838.     (
  839.     int fd, /* file to read in */
  840.     int symEntry, /* position of symbol info in file */
  841.     Elf32_Sym * pSymbol /* points to structure to fill with info */
  842.     )
  843.     {
  844.     int nbytes;
  845.    
  846.     nbytes = sizeof(Elf32_Sym);
  847.     ioctl(fd, FIOSEEK, symEntry);
  848.     if (fioRead (fd, (char *) pSymbol, nbytes) != nbytes)
  849. return (ERROR);
  850.     return (symEntry + nbytes);
  851.     }
  852. /*******************************************************************************
  853. *
  854. * loadElfSymTabRd - read and process the symbol table sections
  855. * This routine searches and reads in the module's current symbol table section.
  856. *
  857. * RETURNS: OK or ERROR.
  858. */
  859. LOCAL STATUS loadElfSymTabRd
  860.     (
  861.     int   fd, /* file to read in */
  862.     int   nextSym, /* position of symbol info in file */
  863.     UINT32  nSyms, /* number of symbols in section */
  864.     Elf32_Sym *  pSymsArray /* array of symbol entries */
  865.     )
  866.     {
  867.     UINT32  symIndex; /* loop counter */
  868.     Elf32_Sym *  pSym; /* pointer to symbol entry */
  869.     /* Loop thru all the symbol in the current symbol table. */
  870.     for (symIndex = 0; symIndex < nSyms; symIndex++)
  871. {
  872. pSym = pSymsArray + symIndex;
  873. /* read in next entry */
  874. if ((nextSym = loadElfSymEntryRd (fd, nextSym, pSym)) == ERROR)
  875.     return (ERROR);
  876. }
  877.     return (OK);
  878.     }
  879. /*******************************************************************************
  880. *
  881. * loadElfSymTablesHandle - handle all symbol tables in module
  882. * This routine allocates
  883. *
  884. * RETURNS: the number of symbol tables, or -1 if something went wrong.
  885. */
  886. LOCAL int loadElfSymTablesHandle
  887.     (
  888.     UINT32 *    pSymTabScnHdrIdxs, /* index of sym table section hdrs */
  889.     Elf32_Shdr *   pScnHdrTbl, /* pointer to section header table */
  890.     int     fd, /* file to read in */
  891.     SYMTBL_REFS *  pSymTblRefs, /* array for module's symbols */
  892.     SYMINFO_REFS * pSymsAdrsRefs /* adrs of ptr to tbl of sym addr tbl */
  893.     )
  894.     {
  895.     UINT32  index; /* loop counter */
  896.     int  symtabNb; /* number of symbol tables in module */
  897.     Elf32_Shdr * pSymTabHdr; /* points to a symbol table header */
  898.     UINT32  nSyms; /* number of syms in current symtab */
  899.     /*
  900.      * In the future, ELF objects file may have more than one symbol table.
  901.      * Then get this number.
  902.      */
  903.     for (symtabNb = 0; pSymTabScnHdrIdxs [symtabNb] != 0; symtabNb++);
  904.     /*
  905.      * Allocate first an array of pointers to symbol tables...
  906.      *
  907.      *                +---+---+---+---+...
  908.      * symTblRefs ->  |   |   |   |   |
  909.      *                +-|-+-|-+-|-+-|-+...
  910.      *                  V   V   V   V
  911.      * Sym tbl 1: +-------+
  912.      *            |symbol |
  913.      *            |entry 1|
  914.      *            +-------+
  915.      *            |symbol |
  916.      *            |entry 2|
  917.      *            +-------+
  918.      *            :       :
  919.      *            :       :
  920.      *
  921.      * Then allocate an array of pointers to symbol address tables...
  922.      */
  923.     if ((*pSymTblRefs = (SYMTBL_REFS) calloc (symtabNb ,
  924.       sizeof (Elf32_Sym *))) == NULL)
  925. return (-1);
  926.     if ((*pSymsAdrsRefs =
  927. (SYMINFO_REFS) calloc (symtabNb ,
  928.  sizeof (SYM_INFO_TBL))) == NULL)
  929. return (-1);
  930.     /*
  931.      * ...then we allocate here the required room for the symbols in all
  932.      * symbol tables and read in the symbols.
  933.      */
  934.     for (index = 0; pSymTabScnHdrIdxs [index] != 0; index++)
  935. {
  936. pSymTabHdr = pScnHdrTbl + pSymTabScnHdrIdxs [index];
  937.         if (pSymTabHdr->sh_entsize != sizeof (Elf32_Sym))
  938.     {
  939.             errnoSet (S_loadElfLib_SYMTAB);
  940.     return (-1);
  941.     }
  942. nSyms = pSymTabHdr->sh_size / pSymTabHdr->sh_entsize;
  943. if ((*pSymTblRefs [index] = (Elf32_Sym *) malloc (pSymTabHdr->sh_size))
  944.     == NULL)
  945.     return (-1);
  946. /* Read in current symbol table contents */
  947. if (loadElfSymTabRd (fd, pSymTabHdr->sh_offset, nSyms,
  948.      *pSymTblRefs [index]) == ERROR)
  949.     return (-1);
  950. /*
  951.  * Create the external undefined symbol address table (for relocations)
  952.  * The size of this table is determined from the number of symbols
  953.  * in the current symbol table. This allow us to store the 
  954.  * external undefined symbols indexed by their number.
  955.  */
  956. if ((*pSymsAdrsRefs [index] =
  957. (SYM_INFO_TBL) malloc (nSyms * sizeof (SYM_INFO))) == NULL)
  958.     return (-1);
  959. }
  960.     return (symtabNb);
  961.     }
  962. /*******************************************************************************
  963. *
  964. * loadElfSymTypeGet - determine the symbol's type
  965. *
  966. * This routine determines the type of a symbol, that is whether a given
  967. * symbol belongs to a text section, a data section, a bss section, is absolute
  968. * or undefined.
  969. *
  970. * RETURNS: the symbol's type.
  971. */
  972. LOCAL SYM_TYPE loadElfSymTypeGet
  973.     (
  974.     Elf32_Sym *  pSymbol, /* pointer to symbol entry */
  975.     Elf32_Shdr * pScnHdrTbl, /* section header table */
  976.     char *       pScnStrTbl         /* ptr to section name string table */
  977.     )
  978.     {
  979. #ifdef INCLUDE_SDA
  980.     SDA_SCN_TYPE sdaScnVal;      /* type of SDA section */
  981. #endif /* INCLUDE_SDA */
  982.     SYM_TYPE  symType = SYM_UNDF; /* internal value for symbol type */
  983.     Elf32_Shdr * pScnHdr; /* pointer to sect header of */
  984. /* the section related to the symbol */
  985.     pScnHdr = pScnHdrTbl + pSymbol->st_shndx;
  986.     /*
  987.      * For absolute symbols, don't consider the section type and flags.
  988.      * Otherwise, the type and flags of the section to which belongs the
  989.      * symbol are tested to determined the type of the symbol.
  990.      */
  991.     if (pSymbol->st_shndx == SHN_ABS)
  992. symType = SYM_ABS;
  993.     else
  994. {
  995. #ifdef INCLUDE_SDA
  996. if (sdaIsRequired)
  997.     {
  998.     /* Determine if the symbol is in the SDA or SDA2 areas.  */
  999.             
  1000.         sdaScnVal = loadElfSdaScnDetermine (pScnStrTbl, pScnHdr, NULL);
  1001.             switch (sdaScnVal)
  1002.              {
  1003.              case SDA_SCN:
  1004.                     symType |= SYM_SDA;
  1005.                     break;
  1006.              case SDA2_SCN:
  1007.                     symType |= SYM_SDA2;
  1008.                     break;
  1009.              }
  1010.     }
  1011. #endif /* INCLUDE_SDA */
  1012. switch (pScnHdr->sh_type)
  1013.     {
  1014.     case (SHT_PROGBITS):
  1015. if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  1016.     (pScnHdr->sh_flags & SHF_EXECINSTR))
  1017.     {
  1018.     /* This is text section */
  1019.     symType |= SYM_TEXT;
  1020.     }
  1021. else if ((pScnHdr->sh_flags & SHF_ALLOC) &&
  1022.  (pScnHdr->sh_flags & SHF_WRITE))
  1023.     {
  1024.     /* This is data section */
  1025.     symType |= SYM_DATA;
  1026.     }
  1027. else if (pScnHdr->sh_flags & SHF_ALLOC)
  1028. #ifdef INCLUDE_SDA
  1029.                     if (sdaIsRequired && (sdaScnVal == SDA2_SCN))
  1030.                         symType |= SYM_DATA;
  1031.     else
  1032. #endif /* INCLUDE_SDA */
  1033.      /*
  1034.       * This is a read only data section.
  1035. * XXX PAD - these sections hold constant data, but
  1036. * since we don't have an appropriate symbol type their
  1037. * contents is considered as "data" by the loader so
  1038. * that tools, such as the shell, behave properly.
  1039.       */
  1040.      symType |= SYM_DATA;
  1041. break;
  1042.     case (SHT_NOBITS):
  1043. if (pScnHdr->sh_flags & SHF_ALLOC)
  1044.     {
  1045.     /* This is a bss section */
  1046.     symType |= SYM_BSS;
  1047.     }
  1048. break;
  1049.     default:
  1050. /*
  1051.  * Well, we don't handle this type of symbol.
  1052.  * Give them type SYM_UNDF.
  1053.  */
  1054. symType = SYM_UNDF;
  1055. break;
  1056.     }
  1057. }
  1058.     return (symType);
  1059.     }
  1060. /*******************************************************************************
  1061. *
  1062. * loadElfSymIsVisible - check whether a symbol must be added to the symtable
  1063. *
  1064. * This routine determines whether or not a symbol must be added to the Target's
  1065. * symbol table, based on the symbol's information and the load flags.
  1066. *
  1067. * RETURNS: TRUE if the symbol must be added, FALSE otherwise.
  1068. */
  1069. LOCAL BOOL loadElfSymIsVisible
  1070.     (
  1071.     UINT32 symAssoc, /* type of entity associated to the symbol */
  1072.     UINT32 symBinding, /* symbol visibility and behavior */
  1073.     int loadFlag /* control of loader's behavior */
  1074.     )
  1075.     {
  1076.     /* Only consider symbols related to functions and variables (objects) */
  1077.     /* 
  1078.      * XXX The STT_ARM_TFUNC type is used by the gnu compiler to mark 
  1079.      * Thumb functions.  It is not part of the ARM ABI or EABI.
  1080.      *
  1081.      * We also now recognize STT_ARM_16BIT - this is the thumb equivalent
  1082.      * of STT_OBJECT. (SPR 73992)
  1083.      */
  1084.     if (! ((symAssoc == STT_OBJECT)  ||
  1085.            (symAssoc == STT_FUNC)
  1086. #if (CPU_FAMILY == ARM)
  1087.    || (symAssoc == STT_ARM_TFUNC) ||
  1088.    (symAssoc == STT_ARM_16BIT)
  1089. #endif
  1090.    ))
  1091.         return (FALSE);
  1092.     /* Depending on the load flags we add globals and locals or only globals */
  1093.     if (! (((loadFlag & LOAD_LOCAL_SYMBOLS) && (symBinding == STB_LOCAL)) ||
  1094.    ((loadFlag & LOAD_GLOBAL_SYMBOLS) &&
  1095.    ((symBinding == STB_GLOBAL) || (symBinding == STB_WEAK)))))
  1096. return (FALSE);
  1097.     return (TRUE);
  1098.     }
  1099. /*******************************************************************************
  1100. *
  1101. * loadElfSymTabProcess - process an object module symbol table
  1102. *
  1103. * This is passed a pointer to a ELF symbol table and processes
  1104. * each of the external symbols defined therein.  This processing performs
  1105. * two functions:
  1106. *
  1107. *  1) Defined symbols are entered in the target system symbol table as
  1108. *     specified by the "loadFlag" argument:
  1109. * LOAD_ALL_SYMBOLS    = all defined symbols (LOCAL and GLOBAL) are added,
  1110. * LOAD_GLOBAL_SYMBOLS = only external (GLOBAL) symbols are added,
  1111. * LOAD_NO_SYMBOLS     = no symbols are added;
  1112. *
  1113. *  2) Any undefined externals are looked up in the target system symbol table
  1114. *     to determine their values and, if found, entered in an array. This
  1115. *     array is indexed by the symbol number (position in the symbol table).
  1116. *     Note that all symbol values, not just undefined externals, are entered
  1117. *     into this array.  The values are used to perform relocations.
  1118. *
  1119. *     Note that "common" symbols have type undefined external - the value
  1120. *     field of the symbol will be non-zero for type common, indicating
  1121. *     the size of the object.
  1122. *
  1123. * If an undefined external cannot be found in the target symbol table,
  1124. * a warning message is printed, the noUndefSym field of the module is set
  1125. * to FALSE, and the name of the symbol is added to the list in the module.
  1126. * Note that this is not considered as an error since this allows all undefined
  1127. * externals to be looked up.
  1128. *
  1129. * RETURNS: OK or ERROR
  1130. */
  1131. LOCAL STATUS loadElfSymTabProcess
  1132.     (
  1133.     MODULE_ID  moduleId, /* module id */
  1134.     int  loadFlag, /* control of loader's behavior */
  1135.     Elf32_Sym *  pSymsArray, /* pointer to symbols array */
  1136.     SCN_ADRS_TBL sectionAdrsTbl, /* table of sections addresses */
  1137.     SYM_INFO_TBL symsAdrsTbl, /* table to fill with syms address */
  1138.     char *   pStringTable, /* pointer on current string table */
  1139.     SYMTAB_ID  symTbl, /* symbol table to feed */
  1140.     UINT32  symNumber, /* number of syms in current symtab */
  1141.     Elf32_Shdr * pScnHdrTbl, /* section header table */
  1142.     char *       pScnStrTbl,          /* ptr to section name string  table */
  1143.     SEG_INFO *   pSeg                   /* info about loaded segments */
  1144.     )
  1145.     {
  1146.     char *   name; /* symbol name (plus EOS) */
  1147.     Elf32_Sym *  pSymbol; /* current symbol being processed */
  1148.     SYM_TYPE  symType; /* internal value for symbol type */
  1149.     UINT32  symIndex; /* symbol index */
  1150.     SYM_ADRS  adrs = NULL; /* table resident symbol address */
  1151.     SYM_ADRS  bias = NULL; /* section relative address */
  1152.     SCN_ADRS *  pScnAddr = NULL; /* addr where section is loaded */
  1153.     STATUS  status = OK; /* ERROR if something is wrong */
  1154.     UINT32  symBinding; /* symbol visibility and behavior */
  1155.     UINT32  symAssoc; /* type of entity associated to sym */
  1156.     UINT32  commonSize; /* size of common symbol when aligned */
  1157.     UINT32  commonAlignment; /* alignment of common symbol */
  1158.     /* Loop thru all symbol table entries in object file. */
  1159.     for (symIndex = 0; symIndex < symNumber; symIndex++)
  1160. {
  1161. pSymbol = pSymsArray + symIndex;
  1162. /* Determine the type of processing based on the symbol type */
  1163. symBinding = ELF32_ST_BIND (pSymbol->st_info);
  1164. symAssoc = ELF32_ST_TYPE (pSymbol->st_info);
  1165. /*
  1166.  * Get the symbol name. In ELF, this name is held by the string table
  1167.  * associated to the symbol table in which the symbol entry is
  1168.  * registred.
  1169.  */
  1170. name = pStringTable + pSymbol->st_name;
  1171. /* we throw away "gcc2_compiled." and "___gnu_compiled_c*" symbols */
  1172. /* and __gnu_compiled_c for mips */
  1173. /* XXX this sould be put in a resource file somewhere */
  1174. if ((!strcmp (name, "gcc2_compiled.")) ||
  1175.     (!strncmp (name, "___gnu_compiled_c",17)) ||
  1176.     (!strncmp (name, "__gnu_compiled_c",16)))
  1177.     continue;
  1178. if ((pSymbol->st_shndx != SHN_UNDEF) &&
  1179.     (pSymbol->st_shndx != SHN_COMMON))
  1180.             {
  1181.             /* Symbol is neither an undefined external, nor a common symbol */
  1182.             /*
  1183.      * Bias is not needed either when symbol is absolute.
  1184.              */
  1185.     if (pSymbol->st_shndx == SHN_ABS)
  1186. bias = 0;
  1187.     else
  1188. {
  1189.      /* 
  1190.       * Compute the bias. In ELF is it the base address of the
  1191.       * section when loaded.
  1192.       */
  1193.      pScnAddr = sectionAdrsTbl + pSymbol->st_shndx;
  1194.      bias = *pScnAddr;
  1195. }
  1196.     /* Determine the symbol type */
  1197.     symType = loadElfSymTypeGet (pSymbol, pScnHdrTbl, pScnStrTbl);
  1198.     /*
  1199.      * The STT_ARM_TFUNC type is used by the gnu compiler to mark
  1200.      * Thumb functions.  It is not part of the ARM ABI or EABI.
  1201.      *
  1202.      * The SYM_THUMB flag only needs to be set for 
  1203.      * function (STT_ARM_TFUNC) symbols, not data symbols, since
  1204.      * it's currently only used when doing a relocation, to switch
  1205.      * the low bit of the address of the function to 1 to signal
  1206.      * that the processor should run the code in THUMB mode. 
  1207.      * 
  1208.      * Therefore it does not need to be set for COMMON symbols or 
  1209.      * STT_ARM_16BIT symbols.
  1210.      *
  1211.      * XXX check may need changing if full interworking is
  1212.      * eventually implemented. 
  1213.      * XXX PAD - also we'll try to move this code in an arch 
  1214.      * specific file in the future.  
  1215.      */
  1216. #if (CPU_FAMILY == ARM)
  1217.     /* check if it's a Thumb function */
  1218.     if (symAssoc == STT_ARM_TFUNC)
  1219.         symType |= SYM_THUMB;
  1220. #endif
  1221.             /* Determine if symbol should be put into symbol table. */
  1222.             if (loadElfSymIsVisible (symAssoc, symBinding, loadFlag))
  1223.                 {
  1224.                 if ((symBinding == STB_GLOBAL) || (symBinding == STB_WEAK))
  1225.     symType |= SYM_GLOBAL;
  1226.                 /* Add symbol to target's symbol table. */
  1227. if (symSAdd (symTbl, name, (char *)(pSymbol->st_value +
  1228.     (INT32) bias), symType, moduleId->group) != OK)
  1229.     {
  1230.     printErr ( "Can't add '%s' to symbol tablen", name);
  1231.     status = ERROR;
  1232.     }
  1233.                 }
  1234. /*
  1235.  * For ELF, we add all symbol addresses into an symbol address
  1236.  * table, not only those symbols added in the target symbol
  1237.  * table. This is required by the relocation process.
  1238.  * XXX PAD I think it is better to use an additionnal array
  1239.  * rather than than modifying the symbol's st_value field since
  1240.  * we may need the original field contents in the future.
  1241.  */
  1242. symsAdrsTbl [symIndex].pAddr = (SYM_ADRS)(pSymbol->st_value +
  1243.     (INT32) bias);
  1244.                 symsAdrsTbl [symIndex].type = symType;
  1245.     }
  1246. else
  1247.     {
  1248.             /*
  1249.              * Undefined external symbol or "common" symbol.
  1250.              * A common symbol type is denoted by a special section index.
  1251.              */
  1252.             if (pSymbol->st_shndx == SHN_COMMON)
  1253. {
  1254. /* Follow common symbol management policy. */
  1255.                 commonSize = pSymbol->st_size;
  1256. commonAlignment = pSymbol->st_value;
  1257. if (loadCommonManage (commonSize, commonAlignment, 
  1258.       name, symTbl, &adrs, &symType, loadFlag,
  1259.                                       pSeg,  moduleId->group) != OK)
  1260.     status = ERROR;
  1261. }
  1262.     else
  1263. {
  1264. /* We get rid of the symbol if it is an ELF debug symbol */
  1265. if ((symBinding == STB_LOCAL) && (symAssoc == STT_NOTYPE))
  1266.     continue;
  1267. /* Look up undefined external symbol in symbol table */
  1268. if (symFindByNameAndType (symTbl, name, (char **) &adrs,
  1269.        &symType, SYM_GLOBAL, 
  1270.        SYM_GLOBAL) != OK)
  1271.        {
  1272.     /* symbol not found in symbol table */
  1273.     adrs = NULL;
  1274.            printErr ("Undefined symbol: %s (binding %d type %d)n",
  1275.   name, symBinding, symAssoc);
  1276.     /* 
  1277.      * SPR # 30588 - loader should return NULL when there
  1278.      * are unresolved symbols. 
  1279.      */
  1280.     status = ERROR;
  1281.     }
  1282. }
  1283.             /* add symbol address to externals table */
  1284.             symsAdrsTbl [symIndex].pAddr = adrs;
  1285.             symsAdrsTbl [symIndex].type = symType;
  1286.     }
  1287. }
  1288.     return (status);
  1289.     }
  1290. /*******************************************************************************
  1291. *
  1292. * loadElfSymTableBuild - build the target's symbol table
  1293. *
  1294. * This routine updates the target's symbol table. It processes in turn
  1295. * all the symbol table sections found in the module.
  1296. * RETURNS: OK or ERROR
  1297. */
  1298. LOCAL STATUS loadElfSymTableBuild
  1299.     (
  1300.     MODULE_ID  moduleId, /* module id */
  1301.     int  loadFlag, /* control of loader's behavior */
  1302.     SYMTBL_REFS  symTblRefs, /* pointer to symbols array */
  1303.     SCN_ADRS_TBL sectionAdrsTbl, /* table of sections addresses */
  1304.     SYMINFO_REFS symsAdrsRefs, /* ptr to tbl to fill with syms addr */
  1305.     IDX_TBLS *  pIndexTables, /* pointer to section index tables */
  1306.     SYMTAB_ID  symTbl, /* symbol table to feed */
  1307.     int   fd, /* file to read in */
  1308.     Elf32_Shdr * pScnHdrTbl, /* section header table */
  1309.     char *       pScnStrTbl,          /* ptr to section name string  table */
  1310.     SEG_INFO *   pSeg                   /* info about loaded segments */
  1311.     )
  1312.     {
  1313.     UINT32  index; /* loop counter */
  1314.     Elf32_Shdr * pSymTabHdr; /* points to a symbol table header */
  1315.     UINT32  nSyms; /* number of syms in current symtab */
  1316.     Elf32_Shdr * pStrTabHdr; /* pointer to a string table header */
  1317.     char *   pStringTable; /* pointer on current string table */
  1318.     STATUS       status = OK;           /* ERROR if undefined symbols found */
  1319.     /*
  1320.      * The module symbol tables are now analysed so that every defined symbol
  1321.      * is added to the target symbol table.  Undefined external symbols are
  1322.      * looked up in the target symbol table and their addresses are stored
  1323.      * in the external symbol array (for relocation purpose).
  1324.      * Note that the target symbol table is built when a core file is
  1325.      * processed.
  1326.      */
  1327.     for (index = 0; pIndexTables->pSymTabScnHdrIdxs [index] != 0; index++)
  1328. {
  1329. pSymTabHdr = pScnHdrTbl + pIndexTables->pSymTabScnHdrIdxs [index];
  1330. nSyms = pSymTabHdr->sh_size / pSymTabHdr->sh_entsize;
  1331.   /* get current string table */
  1332. pStrTabHdr = pScnHdrTbl + pSymTabHdr->sh_link;
  1333.     
  1334. if ((pStringTable = (char *) malloc(pStrTabHdr->sh_size)) == NULL)
  1335.     return ERROR;
  1336. if (ioctl(fd, FIOSEEK, pStrTabHdr->sh_offset) == ERROR ||
  1337.             fioRead (fd, pStringTable, pStrTabHdr->sh_size) !=
  1338.                            pStrTabHdr->sh_size)
  1339.             {
  1340.             errnoSet (S_loadElfLib_READ_SECTIONS);
  1341.          loadElfBufferFree ((void **) &pStringTable);
  1342.             return (ERROR);
  1343.     }
  1344. /* build the target symbol table */
  1345. /* 
  1346.  * SPR # 30588 - loader should return NULL when there are unresolved 
  1347.  * symbols.
  1348.  */
  1349. if (loadElfSymTabProcess (moduleId, loadFlag, symTblRefs [index],
  1350.   sectionAdrsTbl, symsAdrsRefs [index],
  1351.   pStringTable, symTbl, nSyms,
  1352.   pScnHdrTbl, pScnStrTbl, pSeg) != OK)
  1353.     {
  1354.     /* 
  1355.      * status is used to record whether _any_ of the calls to
  1356.      * loadElfSymTabProcess has returned ERROR.  Therefore we
  1357.      * set it only in the error case rather than always setting
  1358.      * it to the return value of loadElfSymTabProcess.
  1359.      */
  1360.     status = ERROR;
  1361.     /* 
  1362.      * If the only error is that some symbols were not found, 
  1363.      * continue building the symbol table.  This allows all 
  1364.      * unresolved symbols to be reported in one pass.  
  1365.      * If any other error was encountered, abort the process.
  1366.      */
  1367.     if (errno != S_symLib_SYMBOL_NOT_FOUND)
  1368.         {
  1369. loadElfBufferFree ((void **) &pStringTable);
  1370. return (ERROR);
  1371. }
  1372.     }
  1373. }
  1374.     loadElfBufferFree ((void **) &pStringTable);
  1375.     return status;
  1376.     }
  1377. /******************************************************************************
  1378. *
  1379. * loadElfRelSegRtnGet - return the appropriate relocation routine
  1380. *
  1381. * This routine returns the appropriate relocation routine for the
  1382. * specified CPU.
  1383. *
  1384. * Warning: this routine is replaced by the relocation unit's initialization
  1385. *          routines. It is kept here until all the relocation units are
  1386. *    standardized. It will be removed afterward.
  1387. *
  1388. * RETURNS: the address of a relocation routine, or NULL if none is found.
  1389. *
  1390. * NOMANUAL
  1391. */
  1392. LOCAL FUNCPTR loadElfRelSegRtnGet (void)
  1393.     {
  1394.     #if (CPU_FAMILY == PPC)
  1395. return ((FUNCPTR) &elfPpcSegReloc);
  1396.     #elif (CPU_FAMILY == SPARC || CPU_FAMILY==SIMSPARCSOLARIS)
  1397. return ((FUNCPTR) &elfSparcSegReloc);
  1398.     #elif (CPU_FAMILY == COLDFIRE)
  1399. return ((FUNCPTR) &elfM68kSegReloc);
  1400.     #elif (CPU_FAMILY == SH)
  1401.         return ((FUNCPTR) &elfShSegReloc);
  1402.     #else
  1403.     printErr ("No relocation routine for this CPUn");
  1404.     #endif /* CPU_FAMILY == PPC */
  1405.     return (NULL);
  1406.     }
  1407. /******************************************************************************
  1408. *
  1409. * loadElfSegReloc - relocate the text and data segments
  1410. *
  1411. * This routine relocates the text and data segments stored in the target 
  1412. * memory, using the appropriate relocation routine for the target
  1413. * architecture.
  1414. *
  1415. * Even if the symbol table had missing symbols, we continue with relocation
  1416. * of those symbols that were found. Although the resulting module might not
  1417. * be usable this allows for an easier incremental testing and this also let
  1418. * the user know of all the missing symbols in the system.
  1419. *
  1420. * Note: the relocation is for adapting the code (text and data) of the
  1421. *       loaded module to its installation address and make it executable.
  1422. *       The places in the segments where references to text or data symbols
  1423. *       are made are modified so that they can access the routine or the
  1424. *       variable this symbol represents. This modification is done accordingly
  1425. *       with the specified relocation command (see the relocation unit for the
  1426. *       the architecture). BSS is uninitialized data, so it is never relocated.
  1427. *
  1428. * RETURNS: OK, or ERROR
  1429. */
  1430. LOCAL STATUS loadElfSegReloc
  1431.     (
  1432.     int   fd, /* file to read in */
  1433.     int  loadFlag, /* control of loader's behavior */
  1434.     MODULE_ID  moduleId, /* module id */
  1435.     Elf32_Ehdr * pHdr,                  /* pointer to module header */
  1436.     IDX_TBLS   * pIndexTables, /* pointer to section index tables */
  1437.     Elf32_Shdr * pScnHdrTbl, /* pointer to section headers table */
  1438.     SCN_ADRS_TBL sectionAdrsTbl, /* table of sections addresses */
  1439.     SYMTBL_REFS  symTblRefs, /* pointer to symbols array */
  1440.     SYMINFO_REFS symsAdrsRefs, /* ptr to tbl to fill with syms addr */
  1441.     SYMTAB_ID  symTbl, /* symbol table to feed */
  1442.     SEG_INFO *   pSeg                   /* info about loaded segments */
  1443.     )
  1444.     {
  1445.     Elf32_Shdr * pSymTabHdr; /* points to a symbol table header */
  1446.     Elf32_Shdr * pStrTabHdr; /* pointer to a string table header */
  1447.     Elf32_Shdr * pRelHdr; /* points to a reloc section header */
  1448.     UINT32  index; /* loop counter */
  1449.     UINT32  arrayIdx; /* loop counter */
  1450.     /*
  1451.      * Get the appropriate relocation routine for the architecture.
  1452.      * See also the warning not in loadElfRelSegRtnGet().
  1453.      */
  1454.     if (pElfSegRelRtn == NULL)
  1455. if ((pElfSegRelRtn = loadElfRelSegRtnGet ()) == NULL)
  1456.     return ERROR;
  1457.     /* Loop thru the relocation section headers */
  1458.     for (index = 0; pIndexTables->pRelScnHdrIdxs [index] != 0; index++)
  1459. {
  1460. pRelHdr = pScnHdrTbl + pIndexTables->pRelScnHdrIdxs [index];
  1461. /*
  1462.  * Since there is only one symbol table allowed in ELF object
  1463.  * modules for now, lets just do a loop to find the index of the
  1464.  * required arrays among the external symbol arrays and the symbol
  1465.  * arrays. In the future, it would be better to index these arrays
  1466.  * on the section header indeces rather than on the order of the
  1467.  * symbol tables.
  1468.  */
  1469. for (arrayIdx = 0;
  1470.      pIndexTables->pSymTabScnHdrIdxs [arrayIdx] != pRelHdr->sh_link;
  1471.         arrayIdx++);
  1472. /* get current string table */
  1473. pSymTabHdr = pScnHdrTbl + pRelHdr->sh_link;
  1474. pStrTabHdr = pScnHdrTbl + pSymTabHdr->sh_link;
  1475. if ((* pElfSegRelRtn) (fd, moduleId, loadFlag,
  1476.        pRelHdr->sh_offset,
  1477.        pScnHdrTbl, pRelHdr,
  1478.        sectionAdrsTbl + pRelHdr->sh_info,
  1479.        symsAdrsRefs [arrayIdx],
  1480.        symTblRefs [arrayIdx], symTbl, pSeg) != OK)
  1481.     return ERROR;
  1482. }
  1483.     return OK;
  1484.     }
  1485. /******************************************************************************
  1486. *
  1487. * loadElfTablesAlloc - allocate memory for the tables used by the ELF loader
  1488. *
  1489. * RETURNS: OK or ERROR if the target does not have enough memory available.
  1490. */
  1491. LOCAL STATUS loadElfTablesAlloc
  1492.     (
  1493.     Elf32_Ehdr * pHdr, /* pointer to module header */
  1494.     Elf32_Phdr ** ppProgHdrTbl, /* where to store the adrs of prog hdrs table */
  1495.     Elf32_Shdr ** ppScnHdrTbl, /* where to store the adrs of sect hdrs table */
  1496.     IDX_TBLS   * pIndexTables /* pointer to section index tables */
  1497.     )
  1498.     {
  1499.     /*
  1500.      * Allocate memory for the program and section header tables and also for
  1501.      * section header index tables. The amount of slots allocated for the 
  1502.      * index tables is equal to the total number of sections in the module,
  1503.      * this save us to loop thru the section header table to know how much
  1504.      * sections of each kind actually exist in the module.
  1505.      * Note that the index table contents are initialized to zero, which is
  1506.      * interpreted as a stop flag when the tables are walked.
  1507.      */
  1508.     if ((*ppScnHdrTbl =
  1509.     (Elf32_Shdr *) malloc (pHdr->e_shnum * pHdr->e_shentsize)) == NULL)
  1510. return (ERROR);
  1511.     if ((*ppProgHdrTbl =
  1512.     (Elf32_Phdr *) malloc (pHdr->e_phnum * pHdr->e_phentsize)) == NULL)
  1513. return (ERROR);
  1514.     if ((pIndexTables->pLoadScnHdrIdxs =
  1515. (UINT32 *) calloc (pHdr->e_shnum, sizeof (UINT32))) == NULL)
  1516. return (ERROR);
  1517.     if ((pIndexTables->pSymTabScnHdrIdxs =
  1518. (UINT32 *) calloc (pHdr->e_shnum, sizeof (UINT32))) == NULL)
  1519. return (ERROR);
  1520.     if ((pIndexTables->pRelScnHdrIdxs =
  1521. (UINT32 *)calloc (pHdr->e_shnum, sizeof (UINT32))) == NULL)
  1522. return (ERROR);
  1523.     if ((pIndexTables->pStrTabScnHdrIdxs =
  1524. (UINT32 *) calloc (pHdr->e_shnum, sizeof (UINT32))) == NULL)
  1525. return (ERROR);
  1526.     return (OK);
  1527.     }
  1528. /******************************************************************************
  1529. *
  1530. * loadElfRelocMod - store relocatable module's segments 
  1531. *
  1532. * This routine stores any relocatable module's segments.
  1533. *
  1534. * RETURNS: OK or ERROR if the segment contents can't be store in target memory.
  1535. */
  1536. LOCAL STATUS loadElfRelocMod
  1537.     (
  1538.     SEG_INFO *     pSeg,                /* info about loaded segments */
  1539.     int    fd,  /* file to read in  */
  1540.     char *         pScnStrTbl,       /* ptr to section string  table */
  1541.     IDX_TBLS *     pIndexTables,        /* pointer to section index tables */
  1542.     Elf32_Ehdr *   pHdr,                /* pointer to module header */
  1543.     Elf32_Shdr *   pScnHdrTbl,          /* pointer to section headers table */
  1544.     SCN_ADRS_TBL * pSectionAdrsTbl      /* table of section addr when loaded */
  1545.     )
  1546.     {
  1547.    /* allocate memory for the section adress table */
  1548.     if ((*pSectionAdrsTbl = (SCN_ADRS_TBL) malloc (pHdr->e_shnum *
  1549.                                                    sizeof (SCN_ADRS))) == NULL)
  1550.             return (ERROR);
  1551.     /*
  1552.      * Read in the section contents to assemble the segment: section's contents
  1553.      * are coalesced so that we end up with a three-segment model in memory:
  1554.      * text, data, bss
  1555.      */
  1556.     if (loadElfScnRd (fd, pScnStrTbl, pIndexTables->pLoadScnHdrIdxs,
  1557.                       pScnHdrTbl, *pSectionAdrsTbl, pSeg) != OK)
  1558.         return (ERROR);
  1559.     return (OK);
  1560.     }
  1561. /******************************************************************************
  1562. *
  1563. * loadElfSegStore - store the module's segments in target memory
  1564. *
  1565. * This routine stores the module's segments in target memory.
  1566. * linked or core file).
  1567. *
  1568. * RETURNS: OK or ERROR if the segment contents can't be store in target memory.
  1569. */
  1570. LOCAL STATUS loadElfSegStore
  1571.     (
  1572.     SEG_INFO *    pSeg, /* info about loaded segments */
  1573.     int    loadFlag, /* control of loader's behavior */
  1574.     int     fd, /* file to read in */
  1575.     char *         pScnStrTbl,       /* ptr to section string  table */
  1576.     IDX_TBLS *    pIndexTables, /* pointer to section index tables */
  1577.     Elf32_Ehdr *   pHdr, /* pointer to module header */
  1578.     Elf32_Shdr *   pScnHdrTbl, /* pointer to section headers table */
  1579.     Elf32_Phdr *   pProgHdrTbl, /* pointer to program headers table */
  1580.     SCN_ADRS_TBL * pSectionAdrsTbl /* table of section addr when loaded */
  1581.     )
  1582.     {
  1583.     if (loadElfRelocMod (pSeg, fd, pScnStrTbl, pIndexTables, pHdr, 
  1584. pScnHdrTbl, pSectionAdrsTbl) != OK)
  1585.         return (ERROR);
  1586.     else
  1587.         return (OK);
  1588.     }
  1589. #ifdef INCLUDE_SDA
  1590. /******************************************************************************
  1591. *
  1592. * loadElfSdaScnDetermine - determine the type of SDA section
  1593. *
  1594. * This routine determines to which SDA area belongs a section. It also returns
  1595. * a pointer to the section's name if the parameter pointer is not null.
  1596. *
  1597. * RETURNS : NOT_SDA_SCN, SDA_SCN or SDA2_SCN
  1598. */
  1599. LOCAL SDA_SCN_TYPE loadElfSdaScnDetermine
  1600.     (
  1601.     char *  pScnStrTbl, /* ptr to section name string  table */
  1602.     Elf32_Shdr * pScnHdr,       /* pointer to current section header */
  1603.     char *       sectionName  /* where to return the section name */
  1604.     )
  1605.     {
  1606.     char *  scnName; /* section name (plus EOS) */
  1607.     scnName = pScnStrTbl + pScnHdr->sh_name; 
  1608.     if (sectionName != NULL)
  1609.         sectionName = scnName;
  1610.     if ((strcmp (scnName, ".sdata") == 0) ||
  1611.      (strcmp (scnName, ".sbss") == 0))
  1612.      return (SDA_SCN);
  1613.     if ((strcmp (scnName, ".sdata2") == 0) ||
  1614.         (strcmp (scnName, ".sbss2") == 0))
  1615.         return (SDA2_SCN);
  1616.     return (NOT_SDA_SCN);
  1617.     }
  1618. /******************************************************************************
  1619. *
  1620. * loadElfSdaCreate - Create new memory partitions for the SDA areas
  1621. *
  1622. * This routine allows for handling the SDA and SDA2 areas by creating two new
  1623. * memory partitions.
  1624. *
  1625. * RETURNS: OK, or ERROR if partitions can't be created.
  1626. */
  1627. LOCAL STATUS loadElfSdaCreate
  1628.     (
  1629.     void
  1630.     )
  1631.     {
  1632.     /* Create new memory partition for SDA and SDA2 areas */
  1633.     if ((sdaMemPartId = memPartCreate ((char *) SDA_BASE, SDA_SIZE)) == NULL)
  1634.         {
  1635.         printErr ("Can't create a memory partition for the SDA area.n");
  1636.         return (ERROR);
  1637.         }
  1638.     if ((sda2MemPartId = memPartCreate ((char *) SDA2_BASE, SDA2_SIZE))== NULL)
  1639.         {
  1640.         printErr ("Can't create a memory partition for the SDA2 area.n");
  1641.         return (ERROR);
  1642.         }
  1643.     sdaBaseAddr = (void *) SDA_BASE;
  1644.     sda2BaseAddr = (void *) SDA2_BASE;
  1645.     sdaAreaSize = (int ) SDA_SIZE;
  1646.     sda2AreaSize = (int ) SDA2_SIZE;
  1647.     return (OK);
  1648.     }
  1649. /******************************************************************************
  1650. *
  1651. * loadElfSdaAllocate - allocate memory in SDA and SDA2 memory partitions
  1652. *
  1653. * This routine allocates memory from the SDA and SDA2 memory partitions for,
  1654. * respectively, the module's sdata and sbss sections, and the module's sdata2
  1655. * and sbss2 sections.
  1656. *
  1657. * RETURNS: OK, or ERROR if memory can't be allocated.
  1658. */
  1659. LOCAL STATUS loadElfSdaAllocate
  1660.     (
  1661.     SDA_INFO *   pSda           /* SDA section addresses and sizes */
  1662.     )
  1663.     {
  1664.     void *      pBlock = NULL;  /* start address of allocated mem in SDA area */
  1665.     int         nBytes;         /* total size of SDA/SDA2 sections */
  1666.     nBytes = pSda->sizeSdata + pSda->sizeSbss;
  1667.     if ((nBytes) && ((pBlock = memPartAlloc (pSda->sdaMemPartId,
  1668.                                                    nBytes)) == NULL))
  1669.         {
  1670.         errnoSet (S_loadElfLib_SDA_MALLOC);
  1671.         return (ERROR);
  1672.         }
  1673.     if (pSda->sizeSdata != 0)
  1674.         {
  1675.         pSda->pAddrSdata = pBlock;
  1676.         pSda->flagsSdata = SEG_FREE_MEMORY;
  1677.         }
  1678.     if (pSda->sizeSbss != 0)
  1679.         {
  1680.         pSda->pAddrSbss = (void *)((char *)pBlock + pSda->sizeSdata);
  1681.         if (pSda->sizeSdata == 0)
  1682.             pSda->flagsSbss = SEG_FREE_MEMORY;
  1683.         }
  1684.     nBytes = pSda->sizeSdata2 + pSda->sizeSbss2;
  1685.     if ((nBytes) && ((pBlock = memPartAlloc (pSda->sda2MemPartId,
  1686.                                                    nBytes)) == NULL))
  1687.         {
  1688.         errnoSet (S_loadElfLib_SDA_MALLOC);
  1689.         return (ERROR);
  1690.         }
  1691.     if (pSda->sizeSdata2 != 0)
  1692.         {
  1693.         pSda->pAddrSdata2 = pBlock;
  1694.         pSda->flagsSdata2 = SEG_FREE_MEMORY;
  1695.         }
  1696.     if (pSda->sizeSbss2 != 0)
  1697.         {
  1698.         pSda->pAddrSbss2 = (void *)((char *)pBlock + pSda->sizeSdata2);
  1699.         if (pSda->sizeSdata2 == 0)
  1700.             pSda->flagsSbss2 = SEG_FREE_MEMORY;
  1701.         }
  1702.     return (OK);
  1703.     }
  1704. #endif /* INCLUDE_SDA */
  1705. /*******************************************************************************
  1706. *
  1707. * loadElfScnNaneStrTblRd - read the section name string table
  1708. *
  1709. * This routine reads the section name string table.
  1710. *
  1711. * RETURNS: N/A
  1712. */
  1713. LOCAL char * loadElfScnStrTblRd
  1714.     (
  1715.     FAST int       fd,       /* fd from which to read module */
  1716.     Elf32_Shdr *   pScnHdrTbl, /* pointer to section headers table */
  1717.     Elf32_Ehdr *   pHdr /* pointer to module header */
  1718.     )
  1719.     {
  1720.     char * pScnStrTbl; /* pointer to the section strng  table */
  1721.  
  1722.     if ((pScnStrTbl = malloc(pScnHdrTbl[pHdr->e_shstrndx].sh_size))
  1723. == NULL)
  1724. return (NULL);
  1725.     ioctl(fd, FIOSEEK, pScnHdrTbl[pHdr->e_shstrndx].sh_offset);
  1726.     if (fioRead(fd, pScnStrTbl, pScnHdrTbl[pHdr->e_shstrndx].sh_size)
  1727. != pScnHdrTbl[pHdr->e_shstrndx].sh_size)
  1728. return (NULL);
  1729.     return (pScnStrTbl);
  1730.     }
  1731. /*******************************************************************************
  1732. *
  1733. * loadElfBufferFree - free a buffer previously allocated
  1734. *
  1735. * This routine frees the memory used by a buffer. The buffer pointer is set to
  1736. * NULL afterward.
  1737. *
  1738. * RETURNS: N/A
  1739. */
  1740. LOCAL void loadElfBufferFree
  1741.     (
  1742.     void ** ppBuf
  1743.     )
  1744.     {
  1745.     if (*ppBuf != NULL)
  1746.         {
  1747.         free (*ppBuf);
  1748.         *ppBuf = NULL;
  1749.         }
  1750.     return;
  1751.     }
  1752. #ifdef INCLUDE_SDA
  1753. /******************************************************************************
  1754. *
  1755. * segElfFindByType - find a segment whith its TYPE
  1756. *
  1757. * This routine finds a segment information in a module whith its
  1758. * type.
  1759. *
  1760. * RETURNS: FALSE if it is the good segment
  1761. *    TRUE if it isn't.
  1762. */
  1763. LOCAL BOOL segElfFindByType
  1764.     (
  1765.     SEGMENT_ID     segmentId,   /* The segment to examine */
  1766.     MODULE_ID      moduleId,    /* The associated module */
  1767.     int            type      /* type of the segment to find */
  1768.     )
  1769.     {
  1770.     if (segmentId->type == type)
  1771.   return (FALSE);
  1772.     return (TRUE);
  1773.     }
  1774. /******************************************************************************
  1775. *
  1776. * moduleElfSegAdd - add a segment to a module for ELF format
  1777. *
  1778. * This routine adds segment information to an object module descriptor.  The
  1779. * specific information recorded depends on the format of the object module.
  1780. *
  1781. * The <type> parameter is one of the following:
  1782. * .iP SEGMENT_TEXT 25
  1783. * Segment holds text (code) or literal (constant data).
  1784. * .iP SEGMENT_DATA
  1785. * Segment holds initialized data
  1786. * .iP SEGMENT_BSS
  1787. * Segment holds non initialized data
  1788. *
  1789. * RETURNS: OK, or ERROR.
  1790. */
  1791. LOCAL STATUS moduleElfSegAdd
  1792.     (
  1793.     MODULE_ID   moduleId,       /* module to add segment to*/
  1794.     int         type,           /* segment type */
  1795.     void *      location,       /* segment address */
  1796.     int         length,         /* segment length */
  1797.     int         flags,          /* segment flags */
  1798.     PART_ID     memPartId       /* ID of mem. partition holding the segment */
  1799.     )
  1800.     {
  1801.     SEGMENT_ID segmentId;
  1802.     if (moduleSegAdd(moduleId, type, location, length, flags) == ERROR)
  1803. return (ERROR);
  1804.  
  1805.     /*
  1806.      * We can't have two segments with the same type in a same module.
  1807.      * So, we use this type to find the segment we have added
  1808.      */
  1809.     if ((segmentId = moduleSegEach(moduleId, (FUNCPTR) segElfFindByType, 
  1810. type)) == NULL)
  1811. return (ERROR);
  1812.    
  1813.     segmentId->memPartId = memPartId; 
  1814.     return (OK);
  1815.     }
  1816. #endif /* INCLUDE_SDA */
  1817. /******************************************************************************
  1818. *
  1819. *
  1820. * loadElfAlignGet - determine required alignment for an address or a size
  1821. *
  1822. * This routine determines, from a proposed address or size, how many bytes
  1823. * should be added to get a target-compliant aligned address or size.
  1824. *
  1825. * RETURNS:
  1826. * the number of bytes to be added to the address or to the size to obtain the
  1827. * correct alignment.
  1828. *
  1829. * SEE ALSO
  1830. * .I Tornado API User's Guide: Target Server
  1831. */
  1832. LOCAL UINT32 loadElfAlignGet
  1833.     (
  1834.     UINT32      alignment,      /* value of alignment */
  1835.     void *      pAddrOrSize     /* address or size to check */
  1836.     )
  1837.     {
  1838.     UINT32      nbytes;         /* # bytes for alignment */
  1839.     /* sections may have a null alignment if their size is null */
  1840.     if (alignment > 0)
  1841.         nbytes = (UINT32) pAddrOrSize % alignment;
  1842.     else
  1843.         nbytes = 0;
  1844.     /* compute fitting if not on correct boundary */
  1845.     if (nbytes != 0)
  1846.         nbytes = alignment - nbytes;
  1847.     return (nbytes);
  1848.     }
  1849. /******************************************************************************
  1850. *
  1851. * loadElfFmtManage - process object module
  1852. *
  1853. * This routine is the underlying routine to loadModuleAt().  This interface
  1854. * allows for specification of the symbol table used to resolve undefined
  1855. * external references and to which to add new symbols.
  1856. *
  1857. * One kind of files can be handled : - relocatable files
  1858. *
  1859. * For relocatable files, addresses of segments may or may not be specified.
  1860. * Memory is allocated on the target if required (nothing specified).
  1861. * RETURNS: OK, or ERROR if can't process file or not enough memory or illegal
  1862. *          file format
  1863. *
  1864. * NOMANUAL
  1865. */
  1866. LOCAL MODULE_ID loadElfFmtManage
  1867.     (
  1868.     FAST int  fd,         /* fd from which to read module */
  1869.     int loadFlag, /* control of loader's behavior */
  1870.     void ** ppText, /* load text segment at addr pointed to by */
  1871. /* this ptr, return load addr via this ptr */
  1872.     void ** ppData, /* load data segment at addr pointed to by */
  1873. /* this ptr, return load addr via this ptr */
  1874.     void ** ppBss, /* load bss segment at addr pointed to by */
  1875. /* this ptr, return load addr via this ptr */
  1876.     SYMTAB_ID symTbl /* symbol table to use */
  1877.     )
  1878.     {
  1879.     char         fileName[255]; /* name of object file */
  1880.     Elf32_Ehdr  hdr; /* module header */
  1881.     Elf32_Phdr * pProgHdrTbl = NULL; /* program headers table */
  1882.     Elf32_Shdr * pScnHdrTbl = NULL; /* section headers table */
  1883.     SEG_INFO     seg;             /* segment info struct */
  1884.     MODULE_ID    moduleId; /* molule identifier */
  1885.     SYMTBL_REFS  symTblRefs = NULL; /* table of pointers to symbol tables */
  1886.     IDX_TBLS  indexTables; /* section index tables */
  1887.     SCN_ADRS_TBL sectionAdrsTbl = NULL; /* table of section addr when loaded */
  1888.     UINT32  index; /* loop counter */
  1889.     SYMINFO_REFS symsAdrsRefs = NULL; /* table of ptrs to sym adrs tables */
  1890.     int  symtabNb       = 0; /* number of symbol tables in module */
  1891.     BOOL         modSegAddSucceeded; /* TRUE if moduleSegAdd() succeeds */
  1892. #ifdef INCLUDE_SDA
  1893.     SDA_INFO *   pSda           = NULL; /* SDA section addresses and sizes */
  1894. #endif /* INCLUDE_SDA */
  1895.     char *       pScnStrTbl = NULL; /* ptr to section name string  table */
  1896.     STATUS       status         = OK;   /* ERROR indicates unresolved symbols */
  1897.    
  1898.     /* initialization */
  1899.     memset ((void *)&seg, 0, sizeof (seg));
  1900.     memset ((void *)&indexTables, 0, sizeof (indexTables));
  1901.     /* Set up the module */
  1902.     /*
  1903.      * XXX - JN - The return values of all these calls to ioctl should 
  1904.      * be checked.
  1905.      */
  1906.     ioctl (fd, FIOGETNAME, (int) fileName);
  1907.     moduleId = loadModuleGet (fileName, MODULE_ELF, &loadFlag);
  1908.     if (moduleId == NULL)
  1909.         return (NULL);
  1910.     /* Read object module header */
  1911.     if (loadElfMdlHdrRd (fd, &hdr) != OK)
  1912.         {
  1913.         errnoSet (S_loadElfLib_HDR_READ);
  1914. goto error;
  1915.         }
  1916.     /*
  1917.      * First, we check if the module is really elf, and if it is intended
  1918.      * for the appropriate target architecture.
  1919.      * Note that we may consider the beginning of the file as an ELF header
  1920.      * since loadElfModuleIsOk() only checks the e_ident field.
  1921.      */
  1922.     if (!loadElfModuleIsOk (&hdr))
  1923. {
  1924.         errnoSet (S_loadElfLib_HDR_READ);
  1925. goto error;
  1926. }
  1927.     /* Allocate memory for the various tables */
  1928.     if (loadElfTablesAlloc(&hdr, &pProgHdrTbl, &pScnHdrTbl, 
  1929. &indexTables) != OK)
  1930. goto error;
  1931.     /*
  1932.      * Initialization of additional info related to the Small Data Area on
  1933.      * PowerPC architecture.
  1934.      */
  1935. #ifdef INCLUDE_SDA
  1936.     if (sdaIsRequired)
  1937.         {
  1938.         if (pSda = (SDA_INFO *) calloc (1, sizeof (SDA_INFO)) == NULL)
  1939.     goto error;
  1940.         pSda->pAddrSdata = LD_NO_ADDRESS;
  1941.         pSda->pAddrSbss = LD_NO_ADDRESS;
  1942.         pSda->pAddrSdata2 = LD_NO_ADDRESS;
  1943.         pSda->pAddrSbss2 = LD_NO_ADDRESS;
  1944.         /*
  1945.          * Record the SDAs memory partition IDs and base addresses. These value
  1946.          * are NULL when the core file is being processed but set afterward.
  1947.          */
  1948.         pSda->sdaMemPartId = sdaMemPartId;
  1949.         pSda->sda2MemPartId = sda2MemPartId;
  1950.         pSda->sdaBaseAddr = sdaBaseAddr;
  1951.         pSda->sda2BaseAddr = sda2BaseAddr;
  1952.         pSda->sdaAreaSize = sdaAreaSize;
  1953.         pSda->sda2AreaSize = sda2AreaSize;
  1954.         seg.pAdnlInfo = (void *) pSda;
  1955.         }
  1956. #endif /* INCLUDE_SDA */
  1957.     /* Read program header table if any */
  1958.     if ((hdr.e_phnum != 0) &&
  1959. (loadElfProgHdrTblRd (fd, hdr.e_phoff, pProgHdrTbl,
  1960.       hdr.e_phnum) != OK))
  1961. goto error;
  1962.     /* Read in section headers and record various section header indexes */
  1963.     if ((hdr.e_shnum != 0) &&
  1964. (loadElfScnHdrRd (fd, hdr.e_shoff, pScnHdrTbl,  
  1965. hdr.e_shnum, &indexTables) != OK))
  1966. goto error;
  1967.     pScnStrTbl = loadElfScnStrTblRd(fd, pScnHdrTbl, &hdr); 
  1968.     if (pScnStrTbl == NULL)
  1969.   goto error;
  1970.     /* Replace a null address by a dedicated flag (LD_NO_ADDRESS) */
  1971.     seg.addrText = (ppText == NULL) ? LD_NO_ADDRESS : *ppText;
  1972.     seg.addrData = (ppData == NULL) ? LD_NO_ADDRESS : *ppData;
  1973.     seg.addrBss  = (ppBss  == NULL) ? LD_NO_ADDRESS : *ppBss;
  1974.     /* Determine segment sizes */
  1975.     /* 
  1976.      * XXX seg.flagsXxx mustn't be used between coffSegSizes() and 
  1977.      * loadSegmentsAllocate().
  1978.      */
  1979.     loadElfSegSizeGet (pScnStrTbl,indexTables.pLoadScnHdrIdxs, pScnHdrTbl, 
  1980. &seg);
  1981.     /* Handles all the symbol table sections in the module */
  1982.     if ((symtabNb = loadElfSymTablesHandle (indexTables.pSymTabScnHdrIdxs,
  1983.     pScnHdrTbl, fd, &symTblRefs,
  1984.     &symsAdrsRefs)) == -1)
  1985. goto error;
  1986.     /*
  1987.      * Take in account the SDA areas (this must be done after the call to
  1988.      * loadElfSymTablesHandle() when required (PowerPC).
  1989.      *
  1990.      * Allocate the segments accordingly with user's requirements.
  1991.      */
  1992.     /* 
  1993.      * SPR #21836: loadSegmentsAllocate() allocate memory aligned on 
  1994.      * the max value of sections alignement saved in seg.flagsText,
  1995.      * seg.flagsData, seg.flagsBss.
  1996.      */
  1997.     if (loadSegmentsAllocate((SEG_INFO *) &seg) != OK)
  1998.         {
  1999.         printErr ("could not allocate text and data segmentsn");
  2000. goto error;
  2001. }
  2002. #ifdef INCLUDE_SDA
  2003.     /*
  2004.      * When required (PowerPC), allocate memory from the SDA memory partitions.
  2005.      */
  2006.     if (sdaIsRequired && (loadElfSdaAllocate (pSda) != OK))
  2007.         goto error;
  2008. #endif /* INCLUDE_SDA */
  2009.     /* We are now about to store the segment's contents in the target memory */
  2010.     if (loadElfSegStore (&seg, loadFlag, fd, pScnStrTbl, &indexTables, &hdr,
  2011.  pScnHdrTbl, pProgHdrTbl, &sectionAdrsTbl) != OK)
  2012. goto error;
  2013.     /*
  2014.      * Build / update the target's symbol table with symbols found
  2015.      * in module's symbol tables.
  2016.      */
  2017.     /* 
  2018.      * SPR # 30588 - loader should return NULL when there are unresolved 
  2019.      * symbols.  However, we finish the load before returning.
  2020.      */
  2021.     if (loadElfSymTableBuild (moduleId, loadFlag, symTblRefs, 
  2022.       sectionAdrsTbl, symsAdrsRefs, 
  2023.       &indexTables, symTbl, fd, pScnHdrTbl, 
  2024.       pScnStrTbl, &seg) != OK) 
  2025. {
  2026. if (errno != S_symLib_SYMBOL_NOT_FOUND)
  2027.     goto error;
  2028. else 
  2029.     status = ERROR;
  2030. }
  2031.     /* Relocate text and data segments (if not already linked) */
  2032.     if ((loadElfSegReloc (fd, loadFlag, moduleId, &hdr, &indexTables,
  2033.   pScnHdrTbl, sectionAdrsTbl, symTblRefs,
  2034.   symsAdrsRefs, symTbl, &seg) != OK))
  2035. goto error;
  2036.     /* clean up dynamically allocated temporary buffers */
  2037.     if (symTblRefs != NULL)
  2038. {
  2039. for (index = 0; index < symtabNb; index++)
  2040.     loadElfBufferFree ((void **) &(symTblRefs [index]));
  2041. loadElfBufferFree((void **)&symTblRefs);
  2042. }
  2043.     if (symsAdrsRefs != NULL)
  2044. {
  2045. for (index = 0; index < symtabNb; index++)
  2046.     loadElfBufferFree ((void **) &(symsAdrsRefs [index]));
  2047. loadElfBufferFree ((void **) &symsAdrsRefs);
  2048. }
  2049.     loadElfBufferFree ((void **) &pProgHdrTbl);
  2050.     loadElfBufferFree ((void **) &pScnHdrTbl);
  2051.     loadElfBufferFree ((void **) &(indexTables.pLoadScnHdrIdxs));
  2052.     loadElfBufferFree ((void **) &(indexTables.pSymTabScnHdrIdxs));
  2053.     loadElfBufferFree ((void **) &(indexTables.pRelScnHdrIdxs));
  2054.     loadElfBufferFree ((void **) &(indexTables.pStrTabScnHdrIdxs));
  2055.     loadElfBufferFree ((void **) &sectionAdrsTbl);
  2056.     loadElfBufferFree ((void **) &pScnStrTbl);
  2057.     /* return load addresses, where called for */
  2058.     if (ppText != NULL)
  2059.         *ppText = seg.addrText;
  2060.     if (ppData != NULL)
  2061.         *ppData = seg.addrData;
  2062.     if (ppBss != NULL)
  2063.         *ppBss = seg.addrBss;
  2064.     /* write protect the text if text segment protection is turned on */
  2065. #if (CPU_FAMILY != SIMSPARCSOLARIS) 
  2066.     if (((seg.flagsText & SEG_WRITE_PROTECTION)) &&
  2067. (VM_STATE_SET (NULL, seg.addrText, seg.sizeProtectedText,
  2068.   VM_STATE_MASK_WRITABLE,
  2069.   VM_STATE_WRITABLE_NOT) == ERROR))
  2070. goto error;
  2071. #endif /*(CPU_FAMILY != SIMSPARCSOLARIS) */
  2072.     /* Initialize bss sections */
  2073.     if (seg.sizeBss != 0) /* zero out bss */
  2074. memset (seg.addrBss, 0, seg.sizeBss);
  2075. #ifdef INCLUDE_SDA    
  2076.     if (sdaIsRequired)
  2077. {
  2078. if (pSda->sizeSbss != 0) /* zero out sbss */
  2079.     memset (pSda->pAddrSbss, 0, pSda->sizeSbss);
  2080. if (pSda->sizeSbss2 != 0) /* zero out sbss2 */
  2081.     memset (pSda->pAddrSbss2, 0, pSda->sizeSbss2);
  2082. }
  2083. #endif  /* INCLUDE_SDA */
  2084. #ifdef INCLUDE_SDA
  2085.     /* Just for moduleShow */
  2086.     if (sdaIsRequired)
  2087.         {
  2088.         seg.sizeData += pSda->sizeSdata + pSda->sizeSdata2;
  2089.         seg.sizeBss += pSda->sizeSbss + pSda->sizeSbss2;
  2090.         if ((seg.addrData == LD_NO_ADDRESS) &&
  2091.             ((seg.addrData = pSda->pAddrSdata) == LD_NO_ADDRESS))
  2092.             seg.addrData = pSda->pAddrSdata2;
  2093.         if ((seg.addrBss == LD_NO_ADDRESS) &&
  2094.             ((seg.addrBss = pSda->pAddrSbss) == LD_NO_ADDRESS))
  2095.             seg.addrBss = pSda->pAddrSbss2;
  2096.         }
  2097. #endif /* INCLUDE_SDA */
  2098.     /* If the module was empty or not managable, just give up now */
  2099.     if ((seg.addrText == LD_NO_ADDRESS) &&
  2100.         (seg.addrData == LD_NO_ADDRESS) &&
  2101.         (seg.addrBss == LD_NO_ADDRESS))
  2102.         {
  2103.         printErr ("Object module not loadedn");
  2104.         goto error;
  2105.         }
  2106.     /* flush stub to memory, flush any i-cache inconsistancies */
  2107.     if (seg.sizeText != 0)
  2108. #ifdef  _CACHE_SUPPORT
  2109. cacheTextUpdate (seg.addrText, seg.sizeText);
  2110. #endif  /* _CACHE_SUPPORT */
  2111.     /*
  2112.      * Add the segments to the module information.  This has to happen after
  2113.      * the relocation gets done. If the relocation happens first, the
  2114.      * checksums won't be correct.  Note that the module information is
  2115.      * updated even if the relocation went wrong so that we can more simply
  2116.      * reclaim any target memory with moduleDelete().
  2117.      */
  2118.     modSegAddSucceeded = (moduleSegAdd (moduleId, SEGMENT_TEXT, 
  2119. seg.addrText, seg.sizeText, seg.flagsText) == OK);
  2120.     modSegAddSucceeded |= (moduleSegAdd (moduleId, SEGMENT_DATA, 
  2121. seg.addrData, seg.sizeData, seg.flagsData) == OK);
  2122.     modSegAddSucceeded |= (moduleSegAdd (moduleId, SEGMENT_BSS, 
  2123. seg.addrBss, seg.sizeBss, seg.flagsBss) == OK);
  2124. #ifdef INCLUDE_SDA
  2125.     if (seg.pAdnlInfo != NULL)
  2126.         {
  2127.         modSegAddSucceeded |= (moduleElfSegAdd (moduleId, SEGMENT_SDATA,
  2128.                         ((SDA_INFO *)seg.pAdnlInfo)->pAddrSdata,
  2129.                         ((SDA_INFO *)seg.pAdnlInfo)->sizeSdata,
  2130.                         ((SDA_INFO *)seg.pAdnlInfo)->flagsSdata,
  2131. ((SDA_INFO *)seg.pAdnlInfo)->sdaMemPartId) == OK);
  2132.         modSegAddSucceeded |= (moduleElfSegAdd (moduleId, SEGMENT_SBSS,
  2133.                         ((SDA_INFO *)seg.pAdnlInfo)->pAddrSbss,
  2134.                         ((SDA_INFO *)seg.pAdnlInfo)->sizeSbss,
  2135.                         ((SDA_INFO *)seg.pAdnlInfo)->flagsSbss,
  2136. ((SDA_INFO *)seg.pAdnlInfo)->sdaMemPartId) == OK);
  2137.         modSegAddSucceeded |= (moduleElfSegAdd (moduleId, SEGMENT_SDATA2,
  2138.                         ((SDA_INFO *)seg.pAdnlInfo)->pAddrSdata2,
  2139.                         ((SDA_INFO *)seg.pAdnlInfo)->sizeSdata2,
  2140.                         ((SDA_INFO *)seg.pAdnlInfo)->flagsSdata2,
  2141. ((SDA_INFO *)seg.pAdnlInfo)->sda2MemPartId) == OK);
  2142.         modSegAddSucceeded |= (moduleElfSegAdd (moduleId, SEGMENT_SBSS2,
  2143.                         ((SDA_INFO *)seg.pAdnlInfo)->pAddrSbss2,
  2144.                         ((SDA_INFO *)seg.pAdnlInfo)->sizeSbss2,
  2145.                         ((SDA_INFO *)seg.pAdnlInfo)->flagsSbss2,
  2146. ((SDA_INFO *)seg.pAdnlInfo)->sda2MemPartId) == OK);
  2147.         }
  2148. #endif /* INCLUDE_SDA */
  2149.  
  2150.     if (!modSegAddSucceeded)           /* Something failed! */
  2151.     {
  2152. printErr ("Object module load failedn");
  2153. goto error;
  2154.      }
  2155. #ifdef  INCLUDE_SDA
  2156.     loadElfBufferFree((void **) &seg.pAdnlInfo);
  2157. #endif  /* INCLUDE_SDA */
  2158.     if (status == OK)
  2159.         return (moduleId);
  2160.     else                                /* Unresolved symbols were found */
  2161.         return NULL;
  2162.     /*
  2163.      * error:
  2164.      * free target memory cache nodes, clean up dynamically allocated
  2165.      * temporary buffers and return ERROR.
  2166.      */
  2167. error:
  2168. #ifdef  _CACHE_SUPPORT
  2169.     /* flush stub to memory, flush any i-cache inconsistancies */
  2170.     if (seg.sizeText != 0)
  2171. cacheTextUpdate (seg.addrText, seg.sizeText);
  2172. #endif  /* _CACHE_SUPPORT */
  2173.     loadElfBufferFree ((void **) &pProgHdrTbl);
  2174.     loadElfBufferFree ((void **) &pScnHdrTbl);
  2175.     loadElfBufferFree ((void **) &(indexTables.pLoadScnHdrIdxs));
  2176.     loadElfBufferFree ((void **) &(indexTables.pSymTabScnHdrIdxs));
  2177.     loadElfBufferFree ((void **) &(indexTables.pRelScnHdrIdxs));
  2178.     loadElfBufferFree ((void **) &(indexTables.pStrTabScnHdrIdxs));
  2179.     loadElfBufferFree ((void **) &sectionAdrsTbl);
  2180. #ifdef  INCLUDE_SDA
  2181.     loadElfBufferFree ((void **) &seg.pAdnlInfo);
  2182. #endif  /* INCLUDE_SDA */
  2183.     loadElfBufferFree ((void **) &pScnStrTbl);
  2184.     if (symTblRefs != NULL)
  2185.         {
  2186.         for (index = 0; index < symtabNb; index++)
  2187.             loadElfBufferFree ((void **) &(symTblRefs [index]));
  2188.         loadElfBufferFree((void **)&symTblRefs);
  2189.         }
  2190.     if (symsAdrsRefs != NULL)
  2191.         {
  2192.         for (index = 0; index < symtabNb; index++)
  2193.             loadElfBufferFree ((void **) &(symsAdrsRefs [index]));
  2194.         loadElfBufferFree ((void **) &symsAdrsRefs);
  2195.         }
  2196.     moduleDelete (moduleId);
  2197.     return (NULL);
  2198.     }
  2199. #endif /* (CPU_FAMILY == (MIPS || PPC || SIMSPARCSOLARIS || 
  2200.                   SH || I80X86 || ARM)) */