reloc.inc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. {-
  2. * Copyright (c) 2018 The FreeBSD Foundation
  3. *
  4. * This software was developed by Konstantin Belousov <[email protected]>
  5. * under sponsorship from the FreeBSD Foundation.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. }
  28. //#include <sys/cdefs.h>
  29. //__FBSDID("$FreeBSD: releng/12.1/lib/csu/amd64/reloc.c 339351 2018-10-13 23:52:55Z kib $");
  30. //#include <machine/specialreg.h>
  31. //#include <machine/cpufunc.h>
  32. Type
  33. Elf_Addr = uint64;
  34. PElf_Addr = ^Elf_Addr;
  35. TElfAddrProc = function (feat1,feat2,stdextfeat1,stdextfeat2:uint32):Elf_Addr; cdecl;
  36. const R_X86_64_IRELATIVE = 37;
  37. procedure freebsdIdentTag;nostackframe;assembler;
  38. asm
  39. .section ".note.tag", "a"
  40. .p2align 2
  41. .long 8
  42. .long 4
  43. .long 1
  44. .asciz "FreeBSD"
  45. .long 0
  46. .text
  47. end;
  48. function ELF_R_TYPE(info:elf_addr):uint32;inline;
  49. begin
  50. ELF_R_TYPE:=info and uint32($ffffffff);
  51. end;
  52. {$asmmode intel}
  53. procedure do_cpuid(funcnr : integer; var p);
  54. begin
  55. asm
  56. mov rax,funcnr
  57. cpuid
  58. mov rsi,@p
  59. mov [rsi],eax
  60. mov [rsi+4],ebx
  61. mov [rsi+8],ecx
  62. mov [rsi+12],edx
  63. end['rax','rbx','rcx','rdx','rsi'];
  64. end;
  65. procedure cpuid_count(funcnr : integer;count:integer;var p);
  66. begin
  67. asm
  68. mov rax,funcnr
  69. mov rcx,count
  70. mov rsi,@p
  71. cpuid
  72. mov [rsi],eax
  73. mov [rsi+4],ebx
  74. mov [rsi+8],ecx
  75. mov [rsi+12],edx
  76. end['rax','rbx','rcx','rdx','rsi'];
  77. end;
  78. procedure crt1_handle_rela(r : pelf_rela);
  79. var p : array[0..3] of uint32;
  80. ptr,
  81. where : PElf_Addr;
  82. target : Elf_Addr;
  83. cpu_feature,
  84. cpu_feature2 : uint32;
  85. cpu_stdext_feature,
  86. cpu_stdext_feature2 : uint32;
  87. begin
  88. do_cpuid(1, p);
  89. cpu_feature := p[3];
  90. cpu_feature2 := p[2];
  91. do_cpuid(0, p);
  92. if (p[0] >= 7) then
  93. begin
  94. cpuid_count(7, 0, p);
  95. cpu_stdext_feature := p[1];
  96. cpu_stdext_feature2 := p[2];
  97. end
  98. else
  99. begin
  100. cpu_stdext_feature := 0;
  101. cpu_stdext_feature2 := 0;
  102. end;
  103. case (ELF_R_TYPE(r^.r_info)) of
  104. R_X86_64_IRELATIVE:
  105. begin
  106. ptr := PElf_Addr(r^.r_addend);
  107. where := PElf_Addr (r^.r_offset);
  108. target := TElfAddrProc(ptr)(cpu_feature, cpu_feature2,
  109. cpu_stdext_feature, cpu_stdext_feature2);
  110. where^:=target;
  111. end;
  112. end;
  113. end;