Source code of Windows XP (NT5)
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.

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