Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

697 lines
18 KiB

  1. PAGE ,132
  2. TITLE LDRELOC - SegReloc procedure
  3. .xlist
  4. include gpfix.inc
  5. include kernel.inc
  6. include newexe.inc
  7. include protect.inc
  8. .list
  9. ;externFP FatalExit
  10. externFP GlobalLock
  11. externFP GlobalUnLock
  12. externFP Int21Handler
  13. externFP IFatalAppExit
  14. DataBegin
  15. externW f8087
  16. externB fastFP
  17. ;externW WinFlags
  18. ifndef WINDEBUG
  19. externB szUndefDyn
  20. endif
  21. DataEnd
  22. sBegin CODE
  23. assumes CS,CODE
  24. externNP GetStringPtr
  25. externNP FindOrdinal
  26. externNP EntProcAddress
  27. externNP LoadSegment
  28. externNP GetOwner
  29. externW gdtdsc
  30. externNP GetAccessWord
  31. externNP DPMIProc
  32. DPMICALL MACRO callno
  33. mov ax, callno
  34. call DPMIProc
  35. ENDM
  36. ifdef WOW_x86
  37. externNP get_physical_address
  38. endif
  39. ;-----------------------------------------------------------------------;
  40. ; UndefDynlink
  41. ;
  42. ; If an application has a dynamic link to a loaded library that
  43. ; we can't find we fix up to this think. This way the app
  44. ; will blow up only if it tries to call the entry point.
  45. ;
  46. ; Entry:
  47. ;
  48. ; Returns:
  49. ;
  50. ; Registers Destroyed:
  51. ;
  52. ; History:
  53. ; Wed 10-May-1989 19:28:50 -by- David N. Weise [davidw]
  54. ; Added this nifty comment block!
  55. ;-----------------------------------------------------------------------;
  56. assumes ds,nothing
  57. assumes es,nothing
  58. cProc UndefDynlink,<PUBLIC,FAR>,<ds>
  59. localW foo ; force stack frame
  60. cBegin
  61. SetKernelDS
  62. if KDEBUG
  63. cCall GetOwner,<[bp].savedCS>
  64. mov es,[bp].savedCS
  65. mov bx,[bp].savedIP
  66. sub bx,5
  67. krDebugOut DEB_FERROR, "%AX1 #ES:#BX called undefined dynalink"
  68. ; kerror ERR_LDNAME,<Call to undefined dynlink entry point at >,es,bx
  69. else
  70. push 0
  71. push ds
  72. push dataOffset szUndefDyn
  73. cCall IFatalAppExit ;,<0, ds, dataOffset szUndefDyn>
  74. endif
  75. cEnd
  76. ;-----------------------------------------------------------------------;
  77. ; SegReloc
  78. ;
  79. ;
  80. ; Entry:
  81. ;
  82. ; Returns:
  83. ;
  84. ; Registers Destroyed:
  85. ;
  86. ; History:
  87. ; Thu 25-May-1989 20:16:09 -by- David N. Weise [davidw]
  88. ; Removed the special case code for version 1.01 (linker or windows?) that
  89. ; If BASE fixup for moveable code segment within a DATA segment (V1.01 only)
  90. ; Then force to be PTR fixup.
  91. ;
  92. ; Wed 10-May-1989 19:28:50 -by- David N. Weise [davidw]
  93. ; Added this nifty comment block!
  94. ;-----------------------------------------------------------------------;
  95. assumes ds, nothing
  96. assumes es, nothing
  97. ifdef WOW_x86
  98. .386
  99. cProc SegReloc,<NEAR,PUBLIC>,<si,edi,ds>
  100. else
  101. cProc SegReloc,<NEAR,PUBLIC>,<si,di,ds>
  102. endif
  103. parmW hexe
  104. parmD prleinfo
  105. parmW creloc
  106. parmD pseginfo
  107. parmW fdataseg
  108. parmW fh
  109. localW himpexe
  110. localW hseg
  111. localW pseg
  112. localW hifileoff
  113. localW lofileoff
  114. localV rlerec,<SIZE NEW_RLC>
  115. localW fOsfixup ;bool set if a floating-pt osfixup.
  116. localW old_access
  117. ifdef WOW_x86
  118. localD rover_2
  119. endif
  120. cBegin
  121. les si, pseginfo
  122. mov dx, es:[si].ns_handle ; Get handle to segment
  123. mov hseg, dx
  124. test dl, GA_FIXED
  125. jnz sr_nolock
  126. cCall GlobalLock,<dx>
  127. sr_nolock:
  128. mov pseg, dx
  129. ;; WOW - refer to original win 3.1 code on \\pucus, there were too many ifdefs
  130. ;; in the code. It would have become unreadable to add any more. mattfe
  131. ;; mar 29 93
  132. ;;; Restored the "too many ifdef's" because this code doesn't just
  133. ;;; assemble right for all our platform permutations. I also tried to make it
  134. ;;; readable by adding comments. -neilsa
  135. ;; For 386 version of WOW we use selector 23h to write to vdm memory without
  136. ;; worrying about setting up a selector.
  137. ifndef WOW
  138. ;------------------Original win31 source--------------------------------
  139. .386p
  140. lar eax, edx
  141. shr eax, 8
  142. .286
  143. mov old_access, ax
  144. test al, DSC_CODE_BIT
  145. jz short access_ok
  146. mov al, DSC_PRESENT+DSC_DATA
  147. mov bx, dx
  148. push ds
  149. mov ds, gdtdsc
  150. and bl, not 7
  151. mov word ptr ds:[bx].dsc_access, ax
  152. pop ds
  153. else ; ******** WOW ADDED SOURCE
  154. ifdef WOW_x86
  155. ;------------------WOW source for X86 platforms-------------------------
  156. else; WOW_x86
  157. ;------------------WOW source for NON-X86 platforms---------------------
  158. .386p
  159. lar eax, edx
  160. shr eax, 8
  161. .286
  162. mov old_access, ax
  163. test al, DSC_CODE_BIT
  164. jz short access_ok
  165. mov al, DSC_PRESENT+DSC_DATA
  166. mov bx, dx
  167. push ds
  168. mov ds, gdtdsc
  169. and bl, not 7
  170. mov word ptr ds:[bx].dsc_access, ax
  171. pop ds
  172. endif; WOW_x86
  173. endif; ******** WOW ADDED SOURCE
  174. ;----------------------End of WOW changes-------------------------------
  175. access_ok:
  176. mov fOsfixup,0 ; set flag initially to false.
  177. mov si,OFF_prleinfo
  178. mov ax,SEG_prleinfo
  179. or ax,ax
  180. jz @F
  181. jmp srloop1
  182. @@:
  183. xor dx,dx
  184. xor cx,cx
  185. mov bx,fh
  186. mov ax,4201h
  187. DOSCALL ; Get current file offset
  188. jnc @F
  189. krDebugOut <DEB_ERROR or DEB_krLoadSeg>, "Get file offset failed"
  190. ; Debug_Out "Get file offset failed."
  191. jmps srbadrle1
  192. @@:
  193. mov hifileoff,dx
  194. mov lofileoff,ax
  195. srloop:
  196. mov ax,SEG_prleinfo
  197. or ax,ax ; Did we get a handle to RLE?
  198. jnz srloop1 ; No, continue
  199. mov cx,hifileoff ; OPTIMIZE this to read in more
  200. mov dx,lofileoff ; than one record at a time!!
  201. mov bx,fh
  202. mov ax,4200h
  203. DOSCALL ; Seek to current offset
  204. jnc @F
  205. krDebugOut DEB_ERROR, "Seek failed."
  206. ; Debug_Out "Seek failed."
  207. srbadrle1:
  208. jmp srbadrle
  209. @@:
  210. push ss
  211. pop ds
  212. lea dx,rlerec
  213. mov cx,SIZE NEW_RLC
  214. add lofileoff,cx
  215. adc hifileoff,0
  216. mov ah,3Fh
  217. DOSCALL ; Read next record
  218. jnc @F
  219. krDebugOut DEB_ERROR, "Read record failed"
  220. ; Debug_Out "Read record failed"
  221. jmps srbadrle1
  222. @@:
  223. cmp ax,cx
  224. je @F
  225. krDebugOut DEB_ERROR, "Read #AX bytes, expecting #CX."
  226. jmp srbadrle
  227. srosfijmp:
  228. jmp srosfixup
  229. @@:
  230. mov ax,ss
  231. mov si,dx
  232. srloop1:
  233. mov ds,ax
  234. mov ax,ds:[si].nr_proc
  235. mov cx,NRRTYP
  236. and cl,ds:[si].nr_flags
  237. or cx,cx
  238. jz srint ; Internal Reference
  239. cmp cl,OSFIXUP
  240. je srosfijmp
  241. .errnz NRRINT
  242. mov bx,ds:[si].nr_mod ; Here if Import Ordinal/Name
  243. sub bx,1
  244. jnc @F
  245. krDebugOut DEB_ERROR, "Zero import module."
  246. jmps srbadrle
  247. @@:
  248. shl bx,1
  249. mov es,hexe
  250. add bx,es:[ne_modtab]
  251. mov bx,es:[bx]
  252. mov himpexe,bx
  253. or bx,bx
  254. jz srbadimp
  255. dec cx ; (sleaze) if cx == 2, then Import Name
  256. jz srrord ; else Import Ordinal
  257. .errnz NRRORD - 1
  258. .errnz NRRNAM - 2
  259. srrnam: ; Convert name to ordinal
  260. cCall GetStringPtr,<hexe,fh,ax>
  261. cCall FindOrdinal,<himpexe,dxax,fh>
  262. mov bx,himpexe
  263. or ax,ax
  264. jz srbadimp
  265. srrord:
  266. if KDEBUG
  267. cCall EntProcAddress,<bx,ax,0>; we do want to RIP for failure
  268. else
  269. cCall EntProcAddress,<bx,ax>
  270. endif
  271. jcxz srbadimp
  272. jmp dorle
  273. srbadimp:
  274. if kdebug
  275. mov dx, hExe
  276. mov ax, himpexe
  277. krDebugOut <DEB_WARN or DEB_krLoadSeg>, "%dx1 failed implicit link to %ax0"
  278. endif
  279. mov dx,cs
  280. mov ax,codeOFFSET UndefDynlink
  281. jmp dorle
  282. srbadrle:
  283. jmp srfail
  284. srdone1:
  285. jmp srdone
  286. srint:
  287. mov dl,NRSTYP ; DL = fixup type
  288. and dl,ds:[si].nr_stype
  289. mov cl,ds:[si].nr_segno
  290. or cx,cx
  291. jnz @F
  292. krDebugOut DEB_ERROR, "NULL segment in fixup."
  293. jmp srbadrle
  294. @@:
  295. mov bx,hexe
  296. cmp cl,ENT_MOVEABLE
  297. je srrord
  298. mov es,bx
  299. mov bx,cx
  300. dec bx
  301. cmp es:[ne_cseg],bx
  302. jnbe @F
  303. krDebugOut DEB_ERROR, "Invalid segment in fixup."
  304. jmp srbadrle ; Error if invalid segno
  305. @@:
  306. push ax ; Save offset
  307. shl bx,1
  308. mov ax,bx
  309. shl bx,1
  310. shl bx,1
  311. add bx,ax ; BX *= 10
  312. .errnz 10 - SIZE NEW_SEG1
  313. add bx,es:[ne_segtab]
  314. cmp dl,NRSOFF ; Offset only fixup?
  315. je srint2 ; Yes, go do it then (DX ignored then)
  316. test byte ptr es:[bx].ns_flags, NSALLOCED
  317. jz srint1
  318. mov ax, es:[bx].ns_handle
  319. or ax,ax
  320. jnz @F
  321. krDebugOut DEB_ERROR, "NULL handle."
  322. jmp srbadrle
  323. @@:
  324. test al,GA_FIXED
  325. jnz srint2
  326. HtoS ax
  327. mov cx,ax ; for the jcxz below
  328. jmps srint2
  329. srbadrlej:
  330. jmp srbadrle
  331. srint1:
  332. int 3
  333. int 3
  334. cCall LoadSegment,<es,cx,fh,fh>
  335. srint2:
  336. mov dx,ax
  337. pop ax
  338. or cx,cx
  339. jnz @F
  340. krDebugOut DEB_ERROR, "Can't load segment."
  341. jmp srbadrlej
  342. @@:
  343. dorle:
  344. push ax
  345. push dx
  346. mov ax,SEG_prleinfo
  347. or ax,ax ; Did we get a handle to RLE?
  348. jnz @F ; No, continue
  349. mov ax,ss ; Assume reading from stack
  350. @@:
  351. mov ds,ax
  352. mov bl,NRSTYP
  353. and bl,ds:[si].nr_stype
  354. mov cx,NRADD
  355. and cl,ds:[si].nr_flags
  356. mov di,ds:[si].nr_soff
  357. ifdef WOW_x86
  358. .386
  359. ;; WOW selector optimiaztion
  360. cCall get_physical_address,<pseg>
  361. shl edx,16
  362. mov dx,ax
  363. mov rover_2,edx
  364. mov ax,FLAT_SEL
  365. mov ds,ax
  366. movzx edi,di
  367. add edi,edx ; es:edi -> pseg:0
  368. else
  369. mov ds, pseg
  370. endif
  371. pop dx
  372. pop ax
  373. cmp bl,NRSSEG
  374. je srsseg
  375. cmp bl,NRSPTR
  376. je srsptr
  377. cmp bl,NRSOFF
  378. je srsoff
  379. cmp bl,NRSBYTE
  380. je srsbyte
  381. krDebugOut DEB_ERROR, "Unknown fixup #BX"
  382. ife KDEBUG
  383. jmps nextrle
  384. endif
  385. nextrlenz: ; if NZ at this point, something broke
  386. jz nextrle
  387. ; jnz srfail
  388. jmp srfail
  389. nextrle:
  390. mov ax,1
  391. add si,SIZE NEW_RLC
  392. dec creloc
  393. jle srdone2
  394. jmp srloop
  395. srdone2:jmp srdone
  396. ; Lo-byte fixup chain (always additive)
  397. beg_fault_trap srfailGP
  398. srsbyte:
  399. ifdef WOW_x86
  400. add ds:[edi],al
  401. else
  402. add ds:[di],al
  403. endif
  404. jmp nextrle
  405. ; Offset fixup chain
  406. srsoff:
  407. cmp fOsfixup,0 ; is it a floating-pt. osfixup?
  408. jnz srsosfixup ; yes, goto special case code.
  409. mov dx, ax ; fall through into segment fixup
  410. ; Segment fixup chain
  411. srsseg:
  412. jcxz srsseg1
  413. ifdef WOW_x86
  414. add ds:[edi],dx
  415. else
  416. add ds:[di],dx
  417. endif
  418. jmp nextrle
  419. srsseg1:
  420. or cx, -1
  421. srsseg2:
  422. mov bx,dx
  423. ifdef WOW_x86
  424. xchg word ptr ds:[edi],bx
  425. movzx edi,bx
  426. add edi,rover_2
  427. else
  428. xchg ds:[di],bx
  429. mov di,bx
  430. endif
  431. inc bx
  432. loopnz srsseg2 ; if CX == 0, we're broken
  433. jmp nextrlenz
  434. ; Segment:Offset fixup chain
  435. srsptr:
  436. jcxz srsptr1
  437. ifdef WOW_x86
  438. add word ptr ds:[edi],ax
  439. add word ptr ds:[edi+2],dx
  440. else
  441. add ds:[di],ax
  442. add ds:[di+2],dx
  443. endif
  444. jmp nextrle
  445. srsptr1:
  446. or cx, -1
  447. srsptr2:
  448. mov bx,ax
  449. ifdef WOW_x86
  450. xchg word ptr ds:[edi],bx
  451. mov word ptr ds:[edi+2],dx
  452. movzx edi,bx
  453. add edi,rover_2
  454. else
  455. xchg ds:[di],bx
  456. mov ds:[di+2],dx
  457. mov di,bx
  458. endif
  459. inc bx
  460. loopnz srsptr2
  461. jmp nextrlenz
  462. ; osfixup for floating-point instructions
  463. fINT EQU 0CDH
  464. fFWAIT EQU 09BH
  465. fESCAPE EQU 0D8H
  466. fFNOP EQU 090H
  467. fES EQU 026H
  468. fCS EQU 02Eh
  469. fSS EQU 036h
  470. fDS EQU 03Eh
  471. BEGINT EQU 034h
  472. FIARQQ EQU (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fDS)
  473. FISRQQ EQU (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fSS)
  474. FICRQQ EQU (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fCS)
  475. FIERQQ EQU (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fES)
  476. FIDRQQ EQU (fINT + 256*(BEGINT + 0)) - (fFWAIT + 256*fESCAPE)
  477. FIWRQQ EQU (fINT + 256*(BEGINT + 9)) - (fFNOP + 256*fFWAIT)
  478. FJARQQ EQU 256*(((0 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  479. FJSRQQ EQU 256*(((1 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  480. FJCRQQ EQU 256*(((2 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  481. osfixuptbl label word ; table has 12 entries - six for int
  482. DW FIARQQ, FJARQQ
  483. DW FISRQQ, FJSRQQ
  484. DW FICRQQ, FJCRQQ
  485. DW FIERQQ, 0h
  486. DW FIDRQQ, 0h
  487. DW FIWRQQ, 0h
  488. osfixuptbllen = $-osfixuptbl ; six to convert FWAIT to NOP
  489. DW fFNOP - fFWAIT, 0
  490. DW fFNOP - fFWAIT, 0
  491. DW fFNOP - fFWAIT, 0
  492. DW fFNOP - fFWAIT, 0
  493. DW fFNOP - fFWAIT, 0
  494. DW FIWRQQ, 0h ; leave this one in for emulator
  495. srsosfixup:
  496. ifdef WOW_x86
  497. add word ptr ds:[edi][0],ax
  498. add word ptr ds:[edi][1],dx
  499. else
  500. add ds:[di][0],ax
  501. add ds:[di][1],dx
  502. endif
  503. mov fOsfixup,0 ; clear flag for next record.
  504. jmp nextrle
  505. end_fault_trap
  506. srfailGP:
  507. ; fault_fix_stack
  508. pop ax
  509. pop dx
  510. krDebugOut DEB_ERROR, "Fault in SegReloc #AX #DX"
  511. srfail:
  512. if KDEBUG
  513. mov bx,hexe
  514. ; xor bx,bx
  515. krDebugOut DEB_ERROR, "%BX1 has invalid relocation record"
  516. ; kerror ERR_LDRELOC,<Invalid relocation record in >,es,bx
  517. endif
  518. xor ax,ax
  519. jmps srdone
  520. ; OSFIXUPs for floating-point instructions.
  521. ;
  522. ; The fixup is applied by adding the first word (ax) to the
  523. ; coprocessor intruction, and for fixups 1-3 also adding the
  524. ; second word (dx) to the instruction+1. Generalize, by having
  525. ; dx=0 for fixups 4-6 and always adding dx to instruction+1.
  526. ;
  527. ; Note: the relocation type is marked NRSOFF by the linker,
  528. ; but we must apply these fixups differently. Here we know
  529. ; it is an osfixup, so set the flag fOsfixup so that later
  530. ; when we test the type, we can apply the fixup correctly.
  531. ;
  532. ; 06-Oct-1987. davidhab.
  533. ; Wed 10-May-1989 19:28:50 -by- David N. Weise [davidw]
  534. ;
  535. ; Actually, due to the way the emulator does fwait polling
  536. ; of exceptions we must send the NOP FWAIT pairs to the
  537. ; emulator even if a math coprocessor is available.
  538. srosfixup:
  539. mov es,hexe
  540. test es:[ne_flags],NEPROT ; OS/2 app
  541. jnz srosf_skip ; then never fix up!
  542. SetKernelDS es
  543. mov bx,ds:[si].nr_mod ; get OSFIXUP id
  544. cmp bx,6 ; is it NOP, FWAIT?
  545. jz srosfixup1 ; if so always fix up!
  546. cmp f8087,94 ; 8087 installed?
  547. jnz srosfixup1 ; No, do OSFIXUP processing
  548. cmp fastFP,0
  549. je srosf_skip
  550. dec bx
  551. shl bx, 2
  552. cmp bx, osfixuptbllen
  553. jae srosfixup2
  554. add bx, osfixuptbllen
  555. jmps fast
  556. srosf_skip:
  557. jmp nextrle ; Yes, skip OSFIXUP processing
  558. srosfixup1:
  559. dec bx ; offset into table is (n-1) * 4
  560. shl bx,1
  561. shl bx,1
  562. cmp bx,osfixuptbllen ; Make sure it is within table bounds
  563. jae srosfixup2 ; No, bad relocation
  564. fast: mov ax,osfixuptbl[bx+0] ; Yes, get relocation value from table
  565. mov dx,osfixuptbl[bx+2] ; get second part of fixup
  566. mov fOsfixup,1 ; set flag to mark our special type.
  567. jmp dorle ; Go apply relocation
  568. srosfixup2:
  569. jmp srbadrle
  570. UnSetKernelDS es
  571. srdone:
  572. push ax
  573. ifndef WOW
  574. ;------------------Original win31 source--------------------------------
  575. mov cx, old_access
  576. test cl, DSC_CODE_BIT
  577. jz short no_reset_access
  578. mov bx, pseg
  579. push ds
  580. mov ds, gdtdsc
  581. and bl, not 7
  582. mov word ptr ds:[bx].dsc_access, cx
  583. pop ds
  584. else ; ******** WOW ADDED SOURCE
  585. ifdef WOW_x86
  586. ;------------------WOW source for X86 platforms-------------------------
  587. else; WOW_x86
  588. ;------------------WOW source for NON-X86 platforms---------------------
  589. mov cx, old_access
  590. test cl, DSC_CODE_BIT
  591. jz short no_reset_access
  592. mov bx, pseg
  593. push ds
  594. mov ds, gdtdsc
  595. and bl, not 7
  596. mov word ptr ds:[bx].dsc_access, cx
  597. pop ds
  598. endif; WOW_x86
  599. endif; ******** WOW ADDED SOURCE
  600. ;----------------------End of WOW changes-------------------------------
  601. no_reset_access:
  602. mov ax, hseg
  603. test al, 1
  604. jnz srdone_nounlock
  605. cCall GlobalUnLock,<ax>
  606. srdone_nounlock:
  607. pop ax
  608. cEnd
  609. sEnd CODE
  610. end