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

VxWorks

开发平台:

C/C++

  1. /* elfI86.c - ELF/Ix86 relocation unit */
  2. /* Copyright 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01b,21nov01,pad  Minor changes: removed unused parameters, test the returned
  8.  value of elfRelocRelEntryRd(), etc.
  9. 01a,12sep01,pad  Backported from TAE 3.1 to T2.2 with necessary adaptations
  10.  (base version: elfI86.c@@/main/tor3_x/15).
  11. */
  12. /*
  13. DESCRIPTION
  14. This file holds the relocation unit for ELF/Intel I86 combination.
  15. Each relocation entry is applied on the sections loaded in the target memory
  16. image, in order to eventually get an executable program linked at the required
  17. address.
  18. The relocation computations handled by this relocation unit are:
  19. R_386_NONE : none
  20. R_386_32 : word32, S + A
  21. R_386_PC32 : word32, S + A - P
  22. With:
  23.    A - the addend used to compute the value of the relocatable field.
  24.    S - the value (address) of the symbol whose index resides in the
  25.        relocation entry. Note that this function uses the value stored
  26.        in the external symbol value array instead of the symbol's
  27.        st_value field.
  28.    P - the place (section offset or address) of the storage unit being
  29.        relocated (computed using r_offset) prior to the relocation.
  30. Per the ELF ABI for the i86 architecture the only relocation entry type
  31. accepted by this relocation unit is Elf32_Rel.
  32. */
  33. /* Defines */
  34. /* Includes */
  35. #include "vxWorks.h"
  36. #include "string.h"
  37. #include "stdio.h"
  38. #include "elf.h"
  39. #include "elftypes.h"
  40. #include "errnoLib.h"
  41. #include "moduleLib.h"
  42. #include "loadLib.h"
  43. #include "loadElfLib.h"
  44. #include "private/vmLibP.h"
  45. #include "symbol.h"
  46. #include "symLib.h"
  47. #include "arch/i86/elfI86.h"
  48. /* Defines */
  49. #define MEM_READ_32(pRelocAdrs, offset)   offset = *((UINT32 *)pRelocAdrs);
  50. #define MEM_WRITE_32(pRelocAdrs, value)   *((UINT32 *) pRelocAdrs) = value;
  51. #define MEM_WRITE_16(pRelocAdrs, value)   *((UINT16 *)pRelocAdrs) = value;
  52. /* Globals */
  53. /* Externals */
  54. IMPORT int elfRelocRelEntryRd (int fd, int posRelocEntry, Elf32_Rel * pReloc);
  55. /* Locals */
  56. LOCAL STATUS relocationSelect
  57.     (
  58.     void * pRelocAdrs,
  59.     Elf32_Rel  * pRelocCmd,
  60.     void * pSymAdrs
  61.     );
  62. LOCAL STATUS elfI86Addr32Reloc
  63.     (
  64.     void * pRelocAdrs,
  65.     void * pSymAdrs
  66.     );
  67. LOCAL STATUS elfI86Pc32Reloc
  68.     (
  69.     void * pRelocAdrs,
  70.     void * pSymAdrs
  71.     );
  72. /*******************************************************************************
  73. *
  74. * elfI86SegReloc - perform relocation for the Intel i86/Pentium family
  75. *
  76. * This routine reads the specified relocation command section and performs
  77. * all the relocations specified therein. Only relocation command from sections
  78. * with section type SHT_REL are considered here.
  79. *
  80. * Absolute symbol addresses are looked up in the <symInfoTbl> table.
  81. *
  82. * RETURNS: OK or ERROR
  83. */
  84. LOCAL STATUS elfI86SegReloc
  85.     (
  86.     int  fd, /* object file to read in */
  87.     MODULE_ID  moduleId, /* ID of object module being relocated */
  88.     int  loadFlag, /* load options (not used here) */
  89.     int  posCurRelocCmd,/* position of current relocation command */
  90.     Elf32_Shdr * pScnHdrTbl, /* ptr to section header table (unused here) */
  91.     Elf32_Shdr * pRelHdr, /* Pointer to relocation section header */
  92.     SCN_ADRS *  pScnAddr, /* Section address once loaded */
  93.     SYM_INFO_TBL symInfoTbl, /* Array of absolute symbol values and types */
  94.     Elf32_Sym *  pSymsArray, /* pointer to symbols array (unused here) */
  95.     SYMTAB_ID   symTbl, /* current symbol table (unused here) */
  96.     SEG_INFO *  pSeg /* section addresses and sizes */
  97.     )
  98.     {
  99.     Elf32_Rel    relocCmd; /* relocation structure */
  100.     UINT32  relocNum; /* number of reloc entries in section */
  101.     UINT32  relocIdx; /* index of the reloc entry being processed */
  102.     void *  pRelocAdrs; /* relocation address */
  103.     void *  pSymAdrs; /* address of symbol involved in relocation */
  104.     BOOL  relocError; /* TRUE when a relocation failed */
  105.     /* Some sanity checking */
  106.     if (pRelHdr->sh_type != SHT_REL)
  107. {
  108. printErr ("Relocation sections of type %d are not supported.n",
  109.   pRelHdr->sh_type);
  110.         errnoSet (S_loadElfLib_RELA_SECTION);
  111. return ERROR;
  112. }
  113.     if (pRelHdr->sh_entsize != sizeof (Elf32_Rel) )
  114. {
  115. printErr ("Wrong relocation entry size.n");
  116.         errnoSet (S_loadElfLib_RELOC);
  117. return ERROR;
  118. }
  119.     /* Get the number of relocation entries */
  120.     relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
  121.     /* Relocation loop */
  122.     relocError = FALSE;
  123.     for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
  124. {
  125. /* Read relocation command (SHT_REL type) */
  126. if ((posCurRelocCmd = elfRelocRelEntryRd (fd,
  127.   posCurRelocCmd,
  128.   &relocCmd)) == ERROR)
  129.     {
  130.     errnoSet (S_loadElfLib_READ_SECTIONS);
  131.     return ERROR;
  132.     }
  133. /*
  134.  * If the target symbol's address is null, then this symbol is
  135.  * undefined. The computation of its value can be out of range and
  136.  * a warning message has already be displayed for this so let's not
  137.  * waste our time on it.
  138.  *
  139.  * Note: ELF32_R_SYM(relocCmd.r_info) gives the index of the symbol
  140.  *       in the module's symbol table. This same index is used to
  141.  *       store the symbol information (address and type for now) in
  142.  *       the symInfoTbl table (see loadElfSymTabProcess()).
  143.  */
  144. if ((pSymAdrs = symInfoTbl [ELF32_R_SYM
  145.  (relocCmd.r_info)].pAddr) == NULL)
  146.     continue;
  147. /*
  148.  * Calculate actual remote address that needs relocation, and
  149.  * perform external or section relative relocation.
  150.  */
  151. pRelocAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
  152. if (relocationSelect (pRelocAdrs, &relocCmd, pSymAdrs) != OK)
  153.     relocError |= TRUE;
  154. }
  155.     if (relocError)
  156. return ERROR;
  157.     else
  158. return OK;
  159.     }
  160. /*******************************************************************************
  161. *
  162. * relocationSelect - select, and execute, the appropriate relocation
  163. *
  164. * This routine selects, then executes, the relocation computation as per the
  165. * relocation command.
  166. *
  167. * NOTE 
  168. * This routine should use two different errnos:
  169. *  - S_loadElfLib_UNSUPPORTED: when a relocation type is not supported on
  170. *    purpose.
  171. *  - S_loadElfLib_UNRECOGNIZED_RELOCENTRY: when a relocation type is not taken
  172. *    into account in this code (default case of the switch).
  173. *
  174. * RETURNS : OK or ERROR if computed value can't be written down in target
  175. *           memory.
  176. */
  177. LOCAL STATUS relocationSelect
  178.     (
  179.     void * pRelocAdrs, /* Addr where the relocation applies  */
  180.     Elf32_Rel * pRelocCmd, /* Relocation command        */
  181.     void * pSymAdrs /* Addr of sym involved in relocation */
  182.     )
  183.     {
  184.     switch (ELF32_R_TYPE (pRelocCmd->r_info))
  185. {
  186. case (R_386_NONE): /* none */
  187.     break;
  188. case (R_386_32): /* word32, S + A */
  189.     if (elfI86Addr32Reloc (pRelocAdrs, pSymAdrs) != OK)
  190. return ERROR;
  191.     break;
  192. case (R_386_PC32): /* word32, S + A - P */
  193.     if (elfI86Pc32Reloc (pRelocAdrs, pSymAdrs) != OK)
  194. return ERROR;
  195.     break;
  196. default:
  197.     printErr ("Unknown relocation type %dn",
  198.       ELF32_R_TYPE (pRelocCmd->r_info));
  199.     errnoSet (S_loadElfLib_UNRECOGNIZED_RELOCENTRY);
  200.     return ERROR;
  201.     break;
  202. }
  203.     return OK;
  204.     }
  205. /*******************************************************************************
  206. *
  207. * elfI86Addr32Reloc - perform the R_386_32 relocation
  208. *
  209. * This routine handles the R_386_32 relocation (word32, S + A).
  210. *
  211. * RETURNS : OK or ERROR if computed value can't be written down in target
  212. *     memory.
  213. */
  214. LOCAL STATUS elfI86Addr32Reloc
  215.     (
  216.     void *  pRelocAdrs, /* address where relocation applies */
  217.     void *  pSymAdrs /* address of symbol involved in relocation */
  218.     )
  219.     {
  220.     UINT32  value; /* relocation value to be stored in memory */
  221.     UINT32  addend; /* constant value used for relocation */
  222.     MEM_READ_32 (pRelocAdrs, addend); /* get addend from memory */
  223.     value = (UINT32)pSymAdrs + addend;
  224.     MEM_WRITE_32(pRelocAdrs, value); /* write back relocated value */
  225.     return OK;
  226.     }
  227. /*******************************************************************************
  228. *
  229. * elfI86Pc32Reloc - perform the R_386_PC32 relocation
  230. *
  231. * This routine handles the R_386_PC32 relocation (word32, S + A - P).
  232. *
  233. * RETURNS : OK or ERROR if computed value can't be written down in target
  234. *     memory.
  235. */
  236. LOCAL STATUS elfI86Pc32Reloc
  237.     (
  238.     void *  pRelocAdrs, /* address where relocation applies */
  239.     void *  pSymAdrs /* address of symbol involved in relocation */
  240.     )
  241.     {
  242.     UINT32  value; /* relocation value to be stored in memory */
  243.     UINT32  addend; /* constant value used for relocation */
  244.     MEM_READ_32 (pRelocAdrs, addend); /* get addend from memory */
  245.     value = (UINT32)pSymAdrs  + addend  - (UINT32)pRelocAdrs;
  246.     MEM_WRITE_32(pRelocAdrs, value); /* write back relocated value */
  247.     return OK;
  248.     }
  249. /******************************************************************************
  250. *
  251. * elfI86ModuleVerify - check the object module format for i86 target arch.
  252. *
  253. * This routine contains the heuristic required to determine if the object
  254. * file belongs to the OMF handled by this OMF reader, with care for the target
  255. * architecture.
  256. * It is the underlying routine for loadElfModuleIsOk().
  257. *
  258. * RETURNS: TRUE or FALSE if the object module can't be handled.
  259. */
  260. LOCAL BOOL elfI86ModuleVerify
  261.     (
  262.     UINT32 machType, /* Module's target arch      */
  263.     BOOL * sdaIsRequired /* TRUE if SDA are used by the arch */
  264.     )
  265.     {
  266.     BOOL moduleIsForTarget = TRUE;   /* TRUE if intended for target */
  267.     *sdaIsRequired = FALSE;
  268.     if (machType != EM_ARCH_MACHINE)
  269. {
  270. moduleIsForTarget = FALSE;
  271. errnoSet (S_loadElfLib_HDR_READ);
  272. }
  273.     return moduleIsForTarget;
  274.     }
  275. /******************************************************************************
  276. *
  277. * elfI86Init - Initialize arch-dependent parts of loader
  278. *
  279. * This routine initializes the function pointers for module verification
  280. * and segment relocation.
  281. *
  282. * RETURNS : OK
  283. */
  284. STATUS elfI86Init
  285.     (
  286.     FUNCPTR * pElfModuleVerifyRtn,
  287.     FUNCPTR * pElfRelSegRtn
  288.     )
  289.     {
  290.     *pElfModuleVerifyRtn = &elfI86ModuleVerify;
  291.     *pElfRelSegRtn   = &elfI86SegReloc;
  292.     return OK;
  293.     }