home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / modutils / obj / obj_sparc64.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-06  |  6.7 KB  |  291 lines

  1. /* Sparc64 specific support for Elf loading and relocation.
  2.    Copyright 1997 Linux International.
  3.  
  4.    Contributed by Jakub Jelinek <jj@sunsite.mff.cuni.cz>
  5.  
  6.    This file is part of the Linux modutils.
  7.  
  8.    This program is free software; you can redistribute it and/or modify it
  9.    under the terms of the GNU General Public License as published by the
  10.    Free Software Foundation; either version 2 of the License, or (at your
  11.    option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software Foundation,
  20.    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  21.  
  22. #ident "$Id: obj_sparc64.c,v 1.1.1.1 1998/01/06 20:51:08 ewt Exp $"
  23.  
  24. #include <stddef.h>
  25. #include <module.h>
  26. #include <obj.h>
  27. #include <util.h>
  28.  
  29.  
  30. /*======================================================================*/
  31.  
  32. struct obj_file *
  33. arch_new_file (void)
  34. {
  35.   return xmalloc(sizeof(struct obj_file));
  36. }
  37.  
  38. struct obj_section *
  39. arch_new_section (void)
  40. {
  41.   return xmalloc(sizeof(struct obj_section));
  42. }
  43.  
  44. struct obj_symbol *
  45. arch_new_symbol (void)
  46. {
  47.   return xmalloc(sizeof(struct obj_symbol));
  48. }
  49.  
  50. #ifdef BROKEN_SPARC64_RELOCS
  51.  
  52. #undef R_SPARC_PLT32
  53. #undef R_SPARC_HIPLT22
  54. #undef R_SPARC_LOPLT10
  55. #undef R_SPARC_PCPLT32
  56. #undef R_SPARC_PCPLT22
  57. #undef R_SPARC_PCPLT10
  58. #undef R_SPARC_10
  59. #undef R_SPARC_11
  60. #undef R_SPARC_64
  61. #undef R_SPARC_OLO10
  62. #undef R_SPARC_HH22
  63. #undef R_SPARC_HM10
  64. #undef R_SPARC_LM22
  65. #undef R_SPARC_PC_HH22
  66. #undef R_SPARC_PC_HM10
  67. #undef R_SPARC_PC_LM22
  68. #undef R_SPARC_WDISP16
  69. #undef R_SPARC_WDISP19
  70. #undef R_SPARC_GLOB_JMP
  71. #undef R_SPARC_7
  72. #undef R_SPARC_5
  73. #undef R_SPARC_6
  74.  
  75. #define R_SPARC_10        24
  76. #define R_SPARC_11        25
  77. #define R_SPARC_64        26
  78. #define R_SPARC_OLO10        27
  79. #define R_SPARC_HH22        28
  80. #define R_SPARC_HM10        29
  81. #define R_SPARC_LM22        30
  82. #define R_SPARC_PC_HH22        31
  83. #define R_SPARC_PC_HM10        32
  84. #define R_SPARC_PC_LM22        33
  85. #define R_SPARC_WDISP16        34
  86. #define R_SPARC_WDISP19        35
  87. #define R_SPARC_GLOB_JMP    36
  88. #define R_SPARC_7        37
  89. #define R_SPARC_5        38
  90. #define R_SPARC_6        39
  91.  
  92. #else
  93.  
  94. #ifndef R_SPARC_64
  95.  
  96. #define R_SPARC_64        32
  97. #define R_SPARC_OLO10        33
  98. #define R_SPARC_HH22        34
  99. #define R_SPARC_HM10        35
  100. #define R_SPARC_LM22        36
  101. #define R_SPARC_PC_HH22        37
  102. #define R_SPARC_PC_HM10        38
  103. #define R_SPARC_PC_LM22        39
  104.  
  105. #endif
  106.                                     
  107. #endif
  108.  
  109. enum obj_reloc
  110. arch_apply_relocation (struct obj_file *ef,
  111.                struct obj_section *targsec,
  112.                struct obj_section *symsec,
  113.                struct obj_symbol *sym,
  114.                Elf64_Rela *rel,
  115.                Elf64_Addr v)
  116. {
  117.   unsigned int *loc = (unsigned int *)(targsec->contents + rel->r_offset);
  118.   unsigned int dot = targsec->header.sh_addr + rel->r_offset;
  119.  
  120.   enum obj_reloc ret = obj_reloc_ok;
  121.  
  122.   switch (ELF64_R_TYPE(rel->r_info))
  123.     {
  124.     case R_SPARC_NONE:
  125.       break;
  126.     case R_SPARC_8:
  127.       if (v > 0xff)
  128.     ret = obj_reloc_overflow;
  129.       *loc = (*loc & ~0xff) | (v & 0xff);
  130.       break;
  131.     case R_SPARC_16:
  132.       if (v > 0xffff)
  133.     ret = obj_reloc_overflow;
  134.       *loc = (*loc & ~0xffff) | (v & 0xffff);
  135.       break;
  136.     case R_SPARC_32:
  137.       *loc = v;
  138.       break;
  139.     case R_SPARC_DISP8:
  140.       v -= dot;
  141.       if (v > 0xff)
  142.         ret = obj_reloc_overflow;
  143.       *loc = (*loc & ~0xff) | (v & 0xff);
  144.       break;
  145.     case R_SPARC_DISP16:
  146.       v -= dot;
  147.       if (v > 0xffff)
  148.     ret = obj_reloc_overflow;
  149.       *loc = (*loc & ~0xffff) | (v & 0xffff);
  150.       break;
  151.     case R_SPARC_DISP32:
  152.       v -= dot;
  153.       *loc = v;
  154.       break;
  155.     case R_SPARC_WDISP30:
  156.       v -= dot;
  157.       if (v % 4)
  158.     ret = obj_reloc_dangerous;
  159.       *loc = (*loc & ~0x3fffffff) | ((v >> 2) & 0x3fffffff);
  160.       break;
  161.     case R_SPARC_WDISP22:
  162.       v -= dot;
  163.       if (v % 4)
  164.     ret = obj_reloc_dangerous;
  165.       *loc = (*loc & ~0x3fffff) | ((v >> 2) & 0x3fffff);
  166.       break;
  167.     case R_SPARC_HI22:
  168.       *loc = (*loc & ~0x3fffff) | (v >> 10);
  169.       break;
  170.     case R_SPARC_22:
  171.       if (v > 0x3fffff)
  172.     ret = obj_reloc_overflow;
  173.       *loc = (*loc & ~0x3fffff) | (v & 0x3fffff);
  174.       break;
  175.     case R_SPARC_13:
  176.       if (v > 0x1fff)
  177.     ret = obj_reloc_overflow;
  178.       *loc = (*loc & ~0x1fff) | (v & 0x1fff);
  179.       break;
  180.     case R_SPARC_LO10:
  181.       *loc = (*loc & ~0x3ff) | (v & 0x3ff);
  182.       break;
  183.  
  184.     case R_SPARC_PC10:
  185.       v -= dot;
  186.       *loc = (*loc & ~0x3ff) | (v & 0x3ff);
  187.       break;
  188.     case R_SPARC_PC22:
  189.       v -= dot;
  190.       *loc = (*loc & ~0x3fffff) | ((v >> 10) & 0x3fffff);
  191.       break;
  192.  
  193.     case R_SPARC_UA32:
  194.       *(((char *)loc) + 0) = (char)(v >> 24);
  195.       *(((char *)loc) + 1) = (char)(v >> 16);
  196.       *(((char *)loc) + 2) = (char)(v >> 8);
  197.       *(((char *)loc) + 3) = (char)v;
  198.       break;
  199.  
  200. #ifdef R_SPARC_10
  201.     case R_SPARC_10:
  202.       if (v > 0x3ff)
  203.     ret = obj_reloc_overflow;
  204.       *loc = (*loc & ~0x3ff) | (v & 0x3ff);
  205.       break;
  206.     case R_SPARC_11:
  207.       if (v > 0x7ff)
  208.     ret = obj_reloc_overflow;
  209.       *loc = (*loc & ~0x7ff) | (v & 0x7ff);
  210.       break;
  211.  
  212. #ifdef R_SPARC_64      
  213.     case R_SPARC_64:
  214.       loc[0] = (v >> 32);
  215.       loc[1] = v;
  216.       break;
  217.     case R_SPARC_OLO10:
  218.       *loc = (*loc & ~0x3ff) | (v & 0x3ff);
  219.       break;
  220.     case R_SPARC_HH22:
  221.       *loc = (*loc & ~0x3fffff) | (v >> 42);
  222.       break;
  223.     case R_SPARC_HM10:
  224.       *loc = (*loc & ~0x3ff) | ((v >> 32) & 0x3ff);
  225.       break;
  226.     case R_SPARC_LM22:
  227.       *loc = (*loc & ~0x3fffff) | ((v >> 10) & 0x3fffff);
  228.       break;
  229.     case R_SPARC_PC_HH22:
  230.       v -= dot;
  231.       *loc = (*loc & ~0x3fffff) | (v >> 42);
  232.       break;
  233.     case R_SPARC_PC_HM10:
  234.       v -= dot;
  235.       *loc = (*loc & ~0x3ff) | ((v >> 32) & 0x3ff);
  236.       break;
  237.     case R_SPARC_PC_LM22:
  238.       v -= dot;
  239.       *loc = (*loc & ~0x3fffff) | ((v >> 10) & 0x3fffff);
  240.       break;
  241. #endif
  242.       
  243.     case R_SPARC_WDISP16:
  244.       v -= dot;
  245.       if (v % 4)
  246.     ret = obj_reloc_dangerous;
  247.       *loc = (*loc & ~0x303fff) | ((v << 4) & 0x300000) | ((v >> 2) & 0x3fff);
  248.       break;
  249.     case R_SPARC_WDISP19:
  250.       v -= dot;
  251.       if (v % 4)
  252.     ret = obj_reloc_dangerous;
  253.       *loc = (*loc & ~0x7ffff) | ((v >> 2) & 0x7ffff);
  254.       break;
  255.     case R_SPARC_7:
  256.       if (v > 0x7f)
  257.     ret = obj_reloc_overflow;
  258.       *loc = (*loc & ~0x7f) | (v & 0x7f);
  259.       break;
  260.     case R_SPARC_5:
  261.       if (v > 0x1f)
  262.     ret = obj_reloc_overflow;
  263.       *loc = (*loc & ~0x1f) | (v & 0x1f);
  264.       break;
  265.     case R_SPARC_6:
  266.       if (v > 0x3f)
  267.     ret = obj_reloc_overflow;
  268.       *loc = (*loc & ~0x3f) | (v & 0x3f);
  269.       break;
  270. #endif /* R_SPARC_10 */
  271.  
  272.     default:
  273.       ret = obj_reloc_unhandled;
  274.       break;
  275.     }
  276.  
  277.   return ret;
  278. }
  279.  
  280. int
  281. arch_create_got (struct obj_file *ef)
  282. {
  283.   return 1;
  284. }
  285.  
  286. int
  287. arch_init_module (struct obj_file *f, struct new_module *mod)
  288. {
  289.   return 1;
  290. }
  291.