sysmach.inc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. type
  2. __darwin_natural_t = cardinal;
  3. __darwin_mach_port_name_t = __darwin_natural_t;
  4. __darwin_mach_port_t = __darwin_mach_port_name_t;
  5. {$ifdef cpu64}
  6. boolean_t = cardinal;
  7. vm_offset_t = ptruint;
  8. vm_size_t = ptruint;
  9. {$else}
  10. boolean_t = longint;
  11. vm_offset_t = __darwin_natural_t;
  12. vm_size_t = __darwin_natural_t;
  13. {$endif}
  14. mach_port_t = __darwin_mach_port_t;
  15. vm_map_t = mach_port_t;
  16. vm_address_t = vm_offset_t;
  17. pvm_address_t = ^vm_address_t;
  18. vm_prot_t = longint;
  19. pvm_prot_t = ^vm_prot_t;
  20. vm_inherit_t = cardinal;
  21. kern_return_t = longint;
  22. const
  23. KERN_SUCCESS = 0;
  24. VM_FLAGS_FIXED = $0000;
  25. VM_FLAGS_ANYWHERE = $0001;
  26. VM_FLAGS_PURGABLE = $0002;
  27. (*
  28. flags that are different between 10.4 and 10.12; fortunately, we don't need them
  29. VM_FLAGS_RANDOM_ADDR = $0008;
  30. VM_FLAGS_NO_CACHE = $0010;
  31. VM_FLAGS_RESILIENT_CODESIGN = $0020;
  32. VM_FLAGS_RESILIENT_MEDIA = $0040;
  33. VM_FLAGS_OVERWRITE = $4000; { delete any existing mappings first }
  34. {*
  35. * VM_FLAGS_SUPERPAGE_MASK
  36. * 3 bits that specify whether large pages should be used instead of
  37. * base pages (!=0), as well as the requested page size.
  38. *}
  39. VM_FLAGS_SUPERPAGE_MASK = $70000; {* bits 0x10000, 0x20000, 0x40000 *}
  40. VM_FLAGS_RETURN_DATA_ADDR = $100000; {* Return address of target data, rather than base of page *}
  41. VM_FLAGS_RETURN_4K_DATA_ADDR = $800000; {* Return 4K aligned address of target data *}
  42. *)
  43. VM_INHERIT_SHARE = vm_inherit_t(0); {* share with child *}
  44. VM_INHERIT_COPY = vm_inherit_t(1); {* copy into child *}
  45. VM_INHERIT_NONE = vm_inherit_t(2); {* absent from child *}
  46. VM_INHERIT_DONATE_COPY = vm_inherit_t(3); {* copy and delete *}
  47. VM_INHERIT_DEFAULT = VM_INHERIT_COPY;
  48. VM_INHERIT_LAST_VALID = VM_INHERIT_NONE;
  49. VM_MEMORY_MALLOC = 1;
  50. VM_MEMORY_MALLOC_SMALL = 2;
  51. VM_MEMORY_MALLOC_LARGE = 3;
  52. VM_MEMORY_MALLOC_HUGE = 4;
  53. VM_MEMORY_SBRK = 5; // uninteresting -- no one should call
  54. VM_MEMORY_REALLOC = 6;
  55. VM_MEMORY_MALLOC_TINY = 7;
  56. var
  57. mach_task_self_: mach_port_t; cvar; external;
  58. vm_page_size: vm_size_t; cvar; external;
  59. vm_kernel_page_size: vm_size_t; cvar; weakexternal; //__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0)
  60. darwin_page_size: vm_size_t;
  61. procedure darwin_init_page_size;
  62. begin
  63. if (@vm_kernel_page_size<>nil) and (vm_kernel_page_size>vm_page_size) then
  64. darwin_page_size:=vm_kernel_page_size
  65. else
  66. darwin_page_size:=vm_page_size;
  67. end;
  68. function mach_task_self: mach_port_t; inline;
  69. begin
  70. result:=mach_task_self_;
  71. end;
  72. function vm_allocate(target: vm_map_t;
  73. address: pvm_address_t;
  74. size: vm_size_t;
  75. flags: longint): kern_return_t; cdecl; external;
  76. function vm_deallocate(target: vm_map_t;
  77. address: vm_address_t;
  78. size: vm_size_t) : kern_return_t; cdecl; external;
  79. function vm_remap(target_task: vm_map_t;
  80. target_address: pvm_address_t;
  81. size: vm_size_t;
  82. mask: vm_offset_t;
  83. flags: longint;
  84. src_task: vm_map_t;
  85. src_address: vm_address_t;
  86. copy: boolean_t;
  87. cur_protection, max_protection: pvm_prot_t;
  88. inheritance: vm_inherit_t): kern_return_t; cdecl; external;
  89. function DARWIN_VM_MAKE_TAG(tag: longint): longint; inline;
  90. begin
  91. result:=longint(cardinal(tag) shl 24);
  92. end;
  93. function darwin_round_page(size: vm_size_t): vm_size_t; inline;
  94. var
  95. local_page_size: vm_size_t;
  96. begin
  97. local_page_size:=darwin_page_size;
  98. result:=(size+local_page_size-1) and not(local_page_size-1);
  99. end;
  100. {$define HAS_SYSOSALLOC}
  101. function SysOSAlloc(size: ptruint): pointer;
  102. var
  103. addr: vm_address_t;
  104. tag: longint;
  105. begin
  106. addr:=0;
  107. if size<=growheapsizesmall then
  108. tag:=DARWIN_VM_MAKE_TAG(VM_MEMORY_MALLOC_TINY) or VM_FLAGS_ANYWHERE
  109. else if size<=growheapsize2 then
  110. tag:=DARWIN_VM_MAKE_TAG(VM_MEMORY_MALLOC) or VM_FLAGS_ANYWHERE
  111. else
  112. tag:=DARWIN_VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE) or VM_FLAGS_ANYWHERE;
  113. if vm_allocate(mach_task_self(), @addr, darwin_round_page(size), tag)=KERN_SUCCESS then
  114. result:=pointer(addr)
  115. else
  116. result:=nil;
  117. end;
  118. {$define HAS_SYSOSFREE}
  119. procedure SysOSFree(p: pointer; size: ptruint);
  120. begin
  121. if vm_deallocate(mach_task_self(), vm_address_t(p), darwin_round_page(size))<>KERN_SUCCESS then
  122. HandleError(204);
  123. end;
  124. {$define FPC_SYSTEM_HAS_SYSOSREALLOC}
  125. function SysOSRealloc(p: pointer;oldsize,newsize: ptruint): pointer;
  126. var
  127. addr: vm_address_t;
  128. oldsize_rounded: vm_address_t;
  129. begin
  130. oldsize_rounded:=darwin_round_page(oldsize);
  131. addr:=vm_address_t(p)+oldsize_rounded;
  132. { fits in the previously allocated block -> return directly}
  133. if (vm_address_t(p+newsize)<=addr) or
  134. { otherwise try to map extra space at the end }
  135. (vm_allocate(mach_task_self(), @addr, darwin_round_page(newsize-oldsize_rounded), DARWIN_VM_MAKE_TAG(VM_MEMORY_REALLOC))=KERN_SUCCESS) then
  136. result:=p
  137. else
  138. result:=nil;
  139. end;