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.

1813 lines
58 KiB

  1. TITLE LDSEG - SegAlloc procedure
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc ; Handle_To_Sel
  7. .list
  8. NSHUGESEG = NSKCACHED ; not first seg of huge segment
  9. ; A huge segment (data object larger than 64K) requires more than one
  10. ; selector, but is part of a single memory allocation block. The first
  11. ; selector is a handle, like any other segment. Subsequent selectors of
  12. ; the huge memory block are _not_ handles, so we can't call MyLock() on
  13. ; them, as the consistency check will fail. We mark these selectors with
  14. ; the NSHUGESEG bit in the flags word. TonyG suggested this.
  15. ; Note that data segments are already loaded, locked, etc, so the call to
  16. ; MyLock is redundant anyway.
  17. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  18. externFP IGlobalFree
  19. externFP IGlobalAlloc
  20. externFP IGlobalReAlloc
  21. externFP IGlobalLock
  22. externFP MyOpenFile
  23. externFP FlushCachedFileHandle
  24. externFP Int21Handler
  25. externFP set_discarded_sel_owner
  26. externFP GetPatchAppRegKey
  27. externFP PatchAppSeg
  28. if KDEBUG
  29. externFP OutputDebugString
  30. endif
  31. if ROM
  32. ;externNP SetROMOwner
  33. externFP FarSetROMOwner
  34. externFP ChangeROMHandle
  35. externFP AllocSelector
  36. externFP IFreeSelector
  37. externNP CloneROMSelector
  38. externFP LZDecode
  39. endif
  40. DataBegin
  41. externB Kernel_flags
  42. ;externB fBooting
  43. externB fPadCode
  44. ;externW pGlobalHeap
  45. ;externW MyCSDS
  46. externW Win_PDB
  47. if KDEBUG
  48. externB fLoadTrace
  49. externB fPreloadSeg
  50. endif
  51. if PMODE32
  52. externD FreeArenaCount
  53. extrn CountFreeSel:WORD
  54. endif
  55. DataEnd
  56. sBegin CODE
  57. assumes CS,CODE
  58. assumes DS,NOTHING
  59. assumes ES,NOTHING
  60. ;externNP MyFree
  61. externNP SegReloc
  62. externNP MyAlloc
  63. externNP MyAllocLinear ; MyAlloc with useful parameters
  64. externNP MyLock
  65. externNP GetCachedFileHandle
  66. externNP CloseCachedFileHandle
  67. externNP GetOwner
  68. externNP SetOwner
  69. externNP get_selector_length16
  70. externNP get_rover_2
  71. externNP DiscardTheWorld
  72. IFNDEF NO_APPLOADER
  73. externNP LoadApplSegment
  74. endif ;!NO_APPLOADER
  75. if LDCHKSUM
  76. ;externNP GetChksumAddr
  77. externNP CheckSegChksum
  78. externNP ZeroSegmentChksum
  79. endif
  80. if SDEBUG
  81. externNP DebugDefineSegment
  82. endif
  83. ifdef WOW_x86
  84. externNP get_physical_address
  85. endif
  86. ;-----------------------------------------------------------------------;
  87. ; AllocSeg ;
  88. ; ;
  89. ; Allocates memory for a segment. Does not load the segment. Puts ;
  90. ; the handle of the segment into the segment descriptor structure ;
  91. ; in the module database, and updates the flags there to mark the ;
  92. ; segment as allocated but not loaded. Put the segment number into ;
  93. ; the BurgerMaster handle entry. It also changes the .ga_owner to be ;
  94. ; the module database. ;
  95. ; ;
  96. ; Arguments: ;
  97. ; parmD pSegInfo ;
  98. ; ;
  99. ; Returns: ;
  100. ; AX = handle for segment ;
  101. ; ;
  102. ; Error Returns: ;
  103. ; AX = 0 ;
  104. ; ZF = 1 ;
  105. ; ;
  106. ; Registers Preserved: ;
  107. ; SI,DS,ES ;
  108. ; ;
  109. ; Registers Destroyed: ;
  110. ; BX,CX,DX ;
  111. ; ;
  112. ; Calls: ;
  113. ; MyAlloc ;
  114. ; ;
  115. ; History: ;
  116. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  117. ; Handle 64K (big/huge) data segments ;
  118. ; ; ;
  119. ; Mon Feb 09, 1987 10:29:16p -by- David N. Weise [davidw] ;
  120. ; Added this nifty comment block. ;
  121. ;-----------------------------------------------------------------------;
  122. assumes ds,nothing
  123. assumes es,nothing
  124. cProc AllocSeg,<PUBLIC,NEAR>,<si,es>
  125. parmD pSegInfo
  126. cBegin
  127. SetKernelDS
  128. les si,pSegInfo
  129. ; Get size into AX (max of file size and minimum allocation).
  130. mov bx,es:[si].ns_flags
  131. test bl,NSALLOCED ; Already allocated?
  132. jz as0 ; No, allocate it
  133. jmp SHORT as3
  134. as0: mov ax,es:[si].ns_minalloc
  135. xor dx, dx ; if AX == 0
  136. cmp ax, 1 ; then it is really 64K
  137. adc dx, dx
  138. add ax, 2 ; We may have a 1 byte entry point at the
  139. adc dx, 0 ; very end of a segment. PatchCodeHandle
  140. ; will GP trying to decipher the prolog.
  141. ; Also allow space for reading relocation word
  142. cmp si,es:[ne_pautodata]
  143. jne as1
  144. add ax,es:[ne_stack] ; Include stack and heap for data.
  145. jc asfail ; Don't need to handle big auto segs
  146. add ax,es:[ne_heap]
  147. jnc as1
  148. asfail:
  149. krDebugOut DEB_ERROR, "%es2 Automatic Data Segment larger than 64K."
  150. xor ax,ax
  151. asxj: jmp SHORT asx
  152. as1:
  153. ; Allocate space for segment
  154. push bx
  155. push es
  156. cCall MyAllocLinear,<bx,dxax>
  157. pop es
  158. pop bx
  159. or ax,ax
  160. jz asxj
  161. as2:
  162. if ROM
  163. ; If this segment gets loaded from ROM, change the segment handle
  164. ; to be the one that was used to fix-up the ROM code segments. This
  165. ; is the value of ns_sector in the segment table.
  166. test byte ptr es:[si].ns_flags+1,(NSINROM SHR 8)
  167. jz as_not_a_rom_seg
  168. mov bx,es:[si].ns_sector
  169. test dl,GA_FIXED
  170. jnz as_fixed
  171. StoH bx
  172. as_fixed:
  173. cCall ChangeROMHandle,<dx,bx>
  174. mov dx,bx
  175. as_not_a_rom_seg:
  176. endif
  177. mov es:[si].ns_handle,dx ; Handle into seg table
  178. and byte ptr es:[si].ns_flags,not NSLOADED
  179. or byte ptr es:[si].ns_flags,NSALLOCED
  180. mov bx,dx
  181. cCall SetOwner,<ax,es>
  182. as3: mov ax,es:[si].ns_handle
  183. asx:
  184. or ax,ax
  185. cEnd
  186. ;-----------------------------------------------------------------------;
  187. ; LoadSegment ;
  188. ; ;
  189. ; Loads a segment and performs any necessary relocations. ;
  190. ; ;
  191. ; Arguments: ;
  192. ; parmW hExe ;
  193. ; parmW segno ;
  194. ; parmW fh ;
  195. ; parmW isfh ;
  196. ; ;
  197. ; Returns: ;
  198. ; AX = handle of segment ;
  199. ; CX = handle of segment ;
  200. ; DX = handle of segment ;
  201. ; ;
  202. ; Error Returns: ;
  203. ; AX = 0 ;
  204. ; CX = 0 ;
  205. ; ;
  206. ; Registers Preserved: ;
  207. ; DI,SI,DS ;
  208. ; ;
  209. ; Registers Destroyed: ;
  210. ; BX,ES ;
  211. ; ;
  212. ; Calls: ;
  213. ; LoadSegment ;
  214. ; AllocSeg ;
  215. ; LoadApplSegment ;
  216. ; MyOpenFile ;
  217. ; SegLoad ;
  218. ; GlobalAlloc ;
  219. ; MyLock ;
  220. ; SegReloc ;
  221. ; GlobalFree ;
  222. ; ZeroSegmentChksum ;
  223. ; CheckSegChksum ;
  224. ; ;
  225. ; History: ;
  226. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  227. ; ;
  228. ; Tue Oct 27, 1987 06:10:31p -by- David N. Weise [davidw] ;
  229. ; Wrote it. ;
  230. ;-----------------------------------------------------------------------;
  231. assumes ds,nothing
  232. assumes es,nothing
  233. cProc LoadSegment,<PUBLIC,NEAR>,<si,di>
  234. parmW hExe
  235. parmW segno
  236. parmW fh
  237. parmW isfh
  238. localW myfh
  239. localW hrleseg
  240. localD pseginfo
  241. localW creloc
  242. localW hseg
  243. localW fdataseg
  244. localW retries
  245. localW SavePDB
  246. localB fReload
  247. if ROM
  248. localW selROMrle
  249. endif
  250. localW pleaseNoLock ; 1 if shouldn't lock seg
  251. cBegin
  252. mov retries, 2
  253. xor ax,ax
  254. mov hrleseg,ax
  255. mov hseg,ax
  256. mov SavePDB, ax
  257. mov pleaseNoLock, ax
  258. mov fReload, al
  259. if ROM
  260. mov selROMrle,ax
  261. endif
  262. not ax
  263. mov myfh,ax
  264. mov es,hexe
  265. mov si,segno
  266. dec si
  267. cmp es:[ne_cseg],si
  268. jg ls_not_done ; wish we had auto jump sizing...
  269. jmp lsdone
  270. ls_not_done:
  271. shl si,1
  272. mov bx,si
  273. shl si,1
  274. shl si,1
  275. add si,bx
  276. .errnz 10 - SIZE NEW_SEG1
  277. add si,es:[ne_segtab]
  278. mov SEG_pseginfo, es ; Save segment info pointer
  279. mov OFF_pseginfo, si
  280. IFNDEF NO_APPLOADER
  281. test es:[ne_flags],NEAPPLOADER
  282. jnz ls_special_load
  283. ls_not_special_load:
  284. ENDIF ;!NO_APPLOADER
  285. mov bx,es:[si].ns_flags
  286. mov ax, bx
  287. and ax, NSHUGESEG
  288. mov pleaseNoLock, ax
  289. if ROM
  290. test bh,(NSINROM SHR 8) ; Segment in ROM?
  291. jz ls0b ; no, go load it normally
  292. test bl,NSLOADED ; Alread 'loaded' in ROM?
  293. jnz chk_rom_seg
  294. push es
  295. cCall AllocSelector,<0>
  296. pop es
  297. cCall CloneROMSelector,<es:[si].ns_sector,ax>
  298. mov selROMrle,ax
  299. mov fh,ax ; Fake parmas to indicate loading
  300. mov isfh,-1 ; from memory and go load it
  301. jmps ls1b
  302. chk_rom_seg:
  303. test bl,NSALLOCED ; ROM seg allocated & loaded into RAM?
  304. jnz ls0b ; yes, treat normally
  305. mov ax,es:[si].ns_handle ; later code expects this
  306. jmp DefineSeg ; define seg to debugger (maybe)
  307. ls0b:
  308. endif ;ROM
  309. test bl,NSALLOCED
  310. jnz ls1
  311. push bx
  312. cCall AllocSeg,<essi> ; No, so try allocating the segment
  313. pop bx
  314. or ax,ax
  315. jnz ls1b
  316. ls1: mov ax,es:[si].ns_handle
  317. mov hseg,ax
  318. test bl,NSLOADED
  319. jz ls1b
  320. mov fReload,1
  321. jmp lsexit ; so MyLock at lsexit can swap them in
  322. IFNDEF NO_APPLOADER
  323. ls_special_load:
  324. mov ax,segno
  325. cmp ax,1
  326. je ls_not_special_load ;* first segment normal load
  327. test es:[si].ns_flags,NSLOADED
  328. jnz ls_already_loaded
  329. cCall LoadApplSegment, <hExe, fh, ax>
  330. jmp lsx
  331. ls_already_loaded:
  332. mov ax,es:[si].ns_handle
  333. mov hseg,ax
  334. mov fReload,1
  335. jmp lsexit
  336. endif ;!NO_APPLOADER
  337. ls1b:
  338. mov ax,fh
  339. inc ax ; Already have file handle?
  340. jz ls2 ; No, then get one and load segment
  341. dec ax
  342. cmp isfh,ax ; Yes, loading from memory?
  343. jne lsdoit ; Yes, load it now
  344. jmps ls2b ; No, load it now
  345. ls2:
  346. SetKernelDS
  347. mov ax, Win_PDB ; Save what PDB is supposed to be
  348. mov SavePDB, ax ; since we will set it to kernel's PDB
  349. mov ax,-1
  350. cCall GetCachedFileHandle,<hExe,ax,ax> ; Get file handle from cache
  351. ls2b:
  352. mov myfh,ax
  353. mov isfh,ax
  354. inc ax
  355. jnz lsdoit0
  356. cmp SavePDB, ax ; If we saved the PDB, (ax=0)
  357. je @F
  358. push SavePDB ; better restore it!
  359. pop Win_PDB
  360. @@:
  361. jmp lsdone
  362. lsdoit0:
  363. dec ax
  364. lsdoit:
  365. push es
  366. cCall SegLoad,<essi,segno,ax,isfh>
  367. pop es
  368. mov hseg,0
  369. or ax,ax
  370. jz lsexit1
  371. inc ax ; Did we get a file error?
  372. jnz lsloaded
  373. mov bx, myfh
  374. inc bx ; Reading from memory?
  375. jz lsexit1 ; no, fail
  376. dec bx
  377. cmp bx, fh ; We opened the file?
  378. je lsexit1 ; no, fail
  379. ;;; cCall CloseCachedFileHandle,<bx>
  380. mov bx, SavePDB
  381. mov Win_PDB, bx
  382. cCall FlushCachedFileHandle,<hExe> ; Close it
  383. dec retries
  384. jz lsbadfile
  385. jmps ls2 ; and try to re-open it.
  386. UnSetKernelDS
  387. lsbadfile:
  388. krDebugOut DEB_ERROR, "%ES2 I/O error reading segment"
  389. lsexit1:
  390. jmp lsexit
  391. lsloaded:
  392. mov hseg,bx
  393. mov bx,es:[si].ns_flags
  394. test bx,NSRELOC
  395. jnz lm1x
  396. jmp lschksum
  397. lm1x:
  398. and bx,NSDATA
  399. mov fdataseg,bx
  400. mov bx,myfh ; Loading from memory?
  401. inc bx
  402. jnz lm1 ; No, continue
  403. mov es,dx ; Yes, point to relocation info
  404. mov si,cx
  405. cld
  406. lods word ptr es:[si]
  407. mov creloc,ax
  408. jmps lm2
  409. lm1:
  410. dec bx
  411. mov creloc,cx
  412. shl cx,1
  413. shl cx,1
  414. shl cx,1
  415. .errnz 8 - SIZE new_rlc
  416. push bx
  417. push cx
  418. mov ax,GA_MOVEABLE+GA_NODISCARD ; DO NOT WANT FIXED!!
  419. xor bx,bx
  420. regptr xsize,bx,cx
  421. if PMODE32
  422. .386
  423. ; We don't really want to cause an attempt to grow the global arena
  424. ; table or the LDT here!
  425. push ds
  426. SetKernelDS
  427. cmp FreeArenaCount,0 ; free arena?
  428. jz NoFreeArenas ; No
  429. cmp CountFreeSel,0 ; free selector?
  430. NoFreeArenas:
  431. pop ds
  432. UnsetKernelDS
  433. jz lm1a ; No, then read one at a time
  434. .286
  435. endif
  436. cCall IGlobalAlloc,<ax,xsize>
  437. mov hrleseg,ax ; Save handle
  438. or ax,ax ; Did we get the memory
  439. jz lm1a ; No, then read one at a time
  440. cCall IGlobalLock,<ax> ; Get the address of the relocation info
  441. mov si, ax
  442. mov es, dx
  443. pop cx ; Restore byte count
  444. pop bx ; Restore file handle
  445. push ds
  446. mov ds,dx
  447. assumes ds,nothing
  448. xor dx,dx
  449. mov ah,3Fh ; Read in relocation information
  450. DOSCALL
  451. pop ds
  452. assumes ds,nothing
  453. jc lserr2
  454. cmp ax,cx
  455. jne lserr2
  456. jmps lm2
  457. lm1a:
  458. pop cx ; Restore byte count
  459. pop bx ; Restore file handle
  460. xor si,si
  461. mov es,si ; Signal no records read
  462. lm2:
  463. ; Pass pseginfo, not hseg
  464. cCall SegReloc,<hexe,essi,creloc,pseginfo,fdataseg,myfh>
  465. lm2a:
  466. mov cx,hrleseg
  467. jcxz no_hrleseg
  468. push ax
  469. cCall IGlobalFree,<hrleseg>
  470. pop ax
  471. no_hrleseg:
  472. les si,pseginfo
  473. or ax,ax
  474. jnz lschksum
  475. lsdone2:
  476. jmps lsdone
  477. lserr2:
  478. krDebugOut DEB_ERROR, "Error reading relocation records from %es2"
  479. xor ax,ax
  480. jmp lm2a
  481. lschksum:
  482. mov ax, hseg ; in case we aren't locking
  483. Handle_To_Sel al
  484. cmp pleaseNoLock, 0
  485. jnz lschksum1
  486. cCall MyLock,<hseg>
  487. lschksum1:
  488. if LDCHKSUM
  489. push ax
  490. push si
  491. mov si,ax
  492. cCall ZeroSegmentChksum
  493. pop si
  494. cCall CheckSegChksum ; destroys ax, bx, cx, dx, es
  495. pop ax
  496. endif
  497. les si, pseginfo
  498. if ROM
  499. DefineSeg:
  500. if SDEBUG
  501. push ax ; save segment selector
  502. endif
  503. endif
  504. if SDEBUG ; Tell debugger about new segment
  505. cmp pleaseNoLock, 0
  506. jnz keep_secrets
  507. mov bx,es:[ne_restab]
  508. inc bx
  509. mov dx,es:[si].ns_flags
  510. mov si, ax
  511. xor ax, ax
  512. test dx,NSDATA ; test to pass NSKCACHED too
  513. jz sa8
  514. test byte ptr es:[ne_flags],NEINST
  515. jz sa8
  516. mov ax,es:[ne_usage]
  517. dec ax
  518. sa8:
  519. mov cx,segno
  520. dec cx
  521. cCall DebugDefineSegment,<esbx,cx,si,ax,dx>
  522. keep_secrets:
  523. endif
  524. if ROM
  525. if SDEBUG
  526. pop ax ; recover segment selector
  527. endif
  528. mov dx,ax ; in case this is a ROM code seg,
  529. ; MyLock doesn't get called, but we
  530. ; want to return AX & DX = selector
  531. endif
  532. lsexit:
  533. mov cx,hseg
  534. jcxz lsdone
  535. mov ax, cx ; in case we don't lock
  536. mov dx, ax
  537. Handle_To_Sel al
  538. cmp pleaseNoLock, 0
  539. jnz lsdone
  540. cCall MyLock,<cx>
  541. lsdone:
  542. if ROM
  543. mov cx,selROMrle ; If a segment was loaded from ROM,
  544. jcxz @f ; an extra selector was allocated
  545. push ax ; to point to reloc info--free that
  546. cCall IFreeSelector,<cx> ; now.
  547. pop ax
  548. @@:
  549. endif
  550. mov cx,myfh
  551. inc cx
  552. jz lsx
  553. dec cx
  554. cmp fh,cx
  555. je lsx
  556. push ax
  557. SetKernelDS
  558. ;;; cCall CloseCachedFileHandle,<cx>
  559. mov ax, SavePDB
  560. if KDEBUG
  561. or ax, ax
  562. jnz @F
  563. int 3
  564. @@:
  565. endif
  566. mov Win_PDB, ax
  567. UnSetKernelDS
  568. pop ax
  569. public lsx
  570. lsx:
  571. mov es, hExe
  572. test es:[ne_flagsothers], NEHASPATCH
  573. jz ls_exeunt
  574. cmp fReload, 0
  575. jne ls_exeunt
  576. push dx
  577. push ax
  578. cCall GetPatchAppRegKey,<hExe>
  579. mov cx, dx
  580. or cx, ax
  581. jnz @F
  582. ; MCF_MODPATCH is set, but there are no patches
  583. ; in the registry for this module. Turn off the patch flag.
  584. and es:[ne_flagsothers], not NEHASPATCH
  585. jmp short ls_after_patch
  586. @@:
  587. ; reg key in dx:ax
  588. cCall PatchAppSeg,<dx,ax,segno,hseg>
  589. test ax, ax
  590. jz ls_after_patch
  591. ; One or more patches applied, so mark the segment not discardable.
  592. ; PatchAppSeg already cleared GA_DISCARDABLE or GA_DISCCODE in the
  593. ; global arena record.
  594. mov si, pseginfo.off
  595. and es:[si].ns_flags, not NSDISCARD ; mark not discardable
  596. ls_after_patch:
  597. pop ax
  598. pop dx
  599. ls_exeunt:
  600. mov cx,ax
  601. cEnd
  602. GETSEGLEN macro segval
  603. local not_huge_386
  604. if PMODE32
  605. .386p
  606. xor eax, eax ; since we now have huge segments,
  607. mov ax, segval ; we need to be able to handle limit
  608. lsl eax, eax ; values > 64K. On a 386 we just
  609. inc eax ; execute the lsl instruction.
  610. test eax, 0ffff0000h
  611. .286
  612. jz not_huge_386
  613. mov ax, 0 ; 0 == 64K
  614. not_huge_386:
  615. else
  616. cCall get_selector_length16,<segval> ; Get size of segment
  617. endif
  618. endm
  619. ;-----------------------------------------------------------------------;
  620. ; SegLoad ;
  621. ; ;
  622. ; Reads in the data portion of a code or data segment. ;
  623. ; ;
  624. ; It can be confusing decoding how various values of ns_cbseg, ;
  625. ; ns_minalloc, and ns_sector define the size of disk files. I hope ;
  626. ; this table is accurate for all combinations.... ;
  627. ; ;
  628. ; sector cbseg minalloc- Sector in memory is ... ;
  629. ; 0 0 0 - 64K segment, all 0's ;
  630. ; 0 0 m - 'm' bytes, all 0's ;
  631. ; 0 c 0 - illegal (sector = 0 when cbseg != 0) ;
  632. ; 0 c m - illegal (sector = 0 when cbseg != 0) ;
  633. ; s 0 0 - 64K segment on disk at given sector ;
  634. ; s 0 m - illegal (cbseg > minalloc) ;
  635. ; s c 0 - 64K, 'c' from file, 64K-'c' 0's ;
  636. ; s c m - 'm' bytes, 'c' from file, 'm-c' 0's ;
  637. ; ;
  638. ; In other words, cbseg == 0 means 64K when a sector value is given, ;
  639. ; else it means 0 bytes from the file ;
  640. ; ;
  641. ; Arguments: ;
  642. ; parmD pseginfo ;
  643. ; parmW segno ;
  644. ; parmW psegsrc ;
  645. ; parmW isfh ;
  646. ; ;
  647. ; Returns: ;
  648. ; ;
  649. ; Error Returns: ;
  650. ; ;
  651. ; Registers Preserved: ;
  652. ; ;
  653. ; Registers Destroyed: ;
  654. ; ;
  655. ; Calls: ;
  656. ; ;
  657. ; History: ;
  658. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  659. ; Add support for big/huge segments ;
  660. ; ;
  661. ; Tue Oct 27, 1987 06:17:07p -by- David N. Weise [davidw] ;
  662. ; Added this nifty comment block. ;
  663. ;-----------------------------------------------------------------------;
  664. assumes ds,nothing
  665. assumes es,nothing
  666. cProc SegLoad,<NEAR,PUBLIC>,<si,di>
  667. parmD pseginfo
  668. parmW segno
  669. parmW psegsrc
  670. parmW isfh
  671. localW hseg
  672. localW pseg
  673. localW psegdest
  674. localD prleinfo
  675. localW retry
  676. localW segoffset
  677. localW pleaseNoLock ;1 if segment is 64K
  678. localW allocTwice ;if first alloc fails, FreeTheWorld
  679. ifdef WOW_x86
  680. localD rover_2
  681. endif
  682. cBegin
  683. mov retry,1
  684. mov segoffset, 0
  685. mov allocTwice, 1
  686. les si,pseginfo
  687. mov ax,es:[si].ns_handle
  688. mov hseg,ax
  689. Handle_To_Sel al ; in case we don't lock
  690. mov pleaseNoLock, 1
  691. test es:[si].ns_flags, NSHUGESEG
  692. jnz dont_touch ;big segs are always locked and present
  693. mov pleaseNoLock, 0
  694. push es
  695. cCall MyLock,<ax>
  696. pop es
  697. or ax,ax
  698. jz try_alloc ; wish I could "jnz saalloced"
  699. dont_touch:
  700. jmps saalloced
  701. try_alloc:
  702. push es
  703. xor ax,ax
  704. mov bx, es:[si].ns_minalloc
  705. xor dx, dx
  706. cmp bx, 1
  707. adc dx, dx
  708. add bx, 2 ; We may have a 1 byte entry point at the
  709. adc dx, 0 ; very end of a segment. PatchCodeHandle
  710. ; will GP trying to decipher the prolog.
  711. ; Allow room to read relocation word
  712. ife PMODE32
  713. push ds
  714. SetKernelDS
  715. cmp fPadCode, 0
  716. je @F
  717. add bx, 14
  718. adc dx, 0
  719. @@:
  720. pop ds
  721. UnSetKernelDS
  722. endif
  723. cCall IGlobalReAlloc,<hseg,dx,bx,ax>
  724. pop es
  725. cmp hseg,ax
  726. jz sarealloced
  727. saerr2:
  728. test es:[si].ns_flags,NSDISCARD
  729. jz dont_scream
  730. push es
  731. cCall DiscardTheWorld ; Maybe if we try again
  732. pop es
  733. dec allocTwice
  734. jz try_alloc
  735. krDebugOut DEB_ERROR, "Out of mem loading seg %es2"
  736. dont_scream:
  737. jmp saerr1
  738. sarealloced: ; ax == handle
  739. Handle_To_Sel al
  740. cmp pleaseNoLock, 0
  741. jnz saalloced
  742. push es
  743. cCall MyLock,<hseg>
  744. pop es
  745. or ax,ax
  746. jz saerr2
  747. saalloced:
  748. mov pseg,ax
  749. mov psegdest,ax
  750. sareread:
  751. push es
  752. push si
  753. push ds ; We are going to trash this
  754. cld
  755. cmp es:[si].ns_sector,0 ; if sector == 0, then just init
  756. jnz sa_read_from_disk ; segment to all 0's
  757. ; mov cx, es:[si].ns_minalloc ; convert minalloc == 0 to 64K
  758. GETSEGLEN pseg
  759. mov cx, ax
  760. ifdef WOW_x86 ;
  761. .386
  762. ;; WOW we can use the magic flat selector 23h to write to any segment
  763. ;; This saves us calling get_rover_2 which makes an NT system call to set
  764. ;; a temp selector
  765. cCall get_physical_address,<pseg>
  766. shl edx,16
  767. mov dx,ax
  768. mov ax,FLAT_SEL
  769. mov es,ax
  770. xor eax, eax
  771. mov edi,edx ; es:edi -> pseg:0
  772. cmp cx, 1 ; Need to handle case where CX == 0
  773. mov dx, cx
  774. rcr cx, 1
  775. shr cx, 1
  776. movzx ecx,cx
  777. rep stos dword ptr [edi]
  778. mov cx, dx
  779. and cx, 3
  780. rep stos byte ptr [edi]
  781. jmp sa_after_read
  782. else ; 286
  783. cmp cx, 1 ; set CF if 0000
  784. rcr cx, 1 ; this sets CF for odd byte of size
  785. xor ax, ax
  786. xor di, di
  787. mov es, pseg ; start at pseg:0000
  788. call get_rover_2
  789. rep stosw
  790. adc cx, cx
  791. rep stosb ; this case now handled
  792. jmp sa_after_read
  793. endif;
  794. sa_read_from_disk:
  795. mov di,es:[si].ns_cbseg ; #bytes in segment to read
  796. ; If source segment address given then copy segment contents
  797. mov bx,psegsrc ; Get source handle
  798. cmp isfh,bx ; Is source a file handle?
  799. je sa_read_file ; Yes, go read segment from file
  800. ; We are reading from preload buffer, bx == src seg address, di == len
  801. push di ; No, set up for fast copy
  802. mov OFF_prleinfo,di
  803. mov SEG_prleinfo,bx
  804. pop cx
  805. if ROM
  806. mov al,byte ptr es:[si].ns_flags+1 ; Compressed seg in ROM?
  807. and al,(NSINROM OR NSCOMPR) SHR 8
  808. cmp al,(NSINROM OR NSCOMPR) SHR 8 ; Both NSINROM & NSCOMPR must
  809. jnz @f ; be set
  810. jmp sa_exp_seg
  811. @@:
  812. endif
  813. mov ds,bx
  814. ifdef WOW_x86 ;
  815. .386
  816. ;; For WOW on NT we don't want to set the selector unesssarily
  817. cCall get_physical_address,<pseg>
  818. shl edx,16
  819. mov dx,ax
  820. mov rover_2,edx
  821. mov ax,FLAT_SEL
  822. mov es,ax
  823. mov edi,edx ; es:edi -> pseg:0
  824. xor esi,esi
  825. cmp cx, 1 ; set carry if 0 for big/huge segs
  826. mov ax, cx
  827. rcr cx, 1
  828. shr cx, 1
  829. movzx ecx,cx
  830. rep movs dword ptr [edi], dword ptr [esi]
  831. mov cx, ax
  832. and cx, 3
  833. rep movs byte ptr [edi], dword ptr [esi]
  834. sub edi,edx ; make di correct for rest of code
  835. else
  836. mov es,pseg ; Writing to pseg
  837. call get_rover_2
  838. xor si,si
  839. xor di,di
  840. IF ROM
  841. clc ; HACK: 64K segs not allowed in ROM
  842. ; because ns_sector always != 0
  843. ELSE
  844. ; need to handle case where seg size is 64K (cx == 0)
  845. cmp cx, 1 ; set carry if 0 for big/huge segs
  846. ENDIF
  847. ife PMODE32
  848. rcr cx, 1 ; set bit 15 if carry was set
  849. rep movsw
  850. adc cx, cx
  851. rep movsb
  852. else
  853. .386
  854. mov ax, cx
  855. rcr cx, 1
  856. shr cx, 1
  857. rep movsd
  858. mov cx, ax
  859. and cx, 3
  860. rep movsb
  861. .286
  862. endif
  863. endif; WOW_x86
  864. ; we have now read 'cbseg' bytes from preload buffer, di == cbseg
  865. jmp sa_zero_fill_rest
  866. saerr1:
  867. xor ax,ax
  868. jmp sax
  869. sa_read_file:
  870. ; read segment contents from disk file, bx == file handle
  871. ; ax = disk file sector
  872. if 0 ;KDEBUG
  873. push ax
  874. push ds
  875. SetKernelDS
  876. cmp fPreloadSeg, 0
  877. jne SHORT SkipDebugTrace
  878. mov ax, segno
  879. krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "%ES0: reading segment #ax"
  880. SkipDebugTrace:
  881. pop ds
  882. UnSetKernelDS
  883. pop ax
  884. endif
  885. ; Get offset to data portion of segment in DX:AX
  886. mov ax, es:[si].ns_sector
  887. xor dx,dx
  888. mov cx,es:[ne_align]
  889. sa4a:
  890. shl ax,1
  891. adc dx, dx
  892. loop sa4a ; DX:AX = file offset to segment
  893. mov cx,dx ; Seek to beginning of segment data
  894. mov dx,ax
  895. mov ax,4200h ; lseek(bx, sector << align, SEEK_SET)
  896. DOSCALL
  897. jc saerr
  898. mov cx,di ; Get #bytes to read
  899. test es:[si].ns_flags,NSRELOC
  900. jz no_read_extra_word
  901. add cx, 2 ; Relocation word
  902. no_read_extra_word:
  903. mov ds,pseg ; Read segment from file
  904. xor dx,dx
  905. mov ah,3Fh
  906. test es:[si].ns_flags,NSITER
  907. jz @F
  908. call iterated_data_seg
  909. jmps sa_iter_done
  910. @@:
  911. or cx, cx ; if cx == 0 at this point, it is 64K
  912. jnz not_huge_read
  913. cmp es:[si].ns_minalloc,0 ; If minalloc isn't zero too, then the
  914. jnz not_huge_read ; segment is too small. Case should't
  915. ; happen but does for dbwindow, mimic Win 3.0.
  916. mov cx, 8000h
  917. DOSCALL ; read first 32K from disk
  918. jc saerr
  919. add dx, cx ; update destination address
  920. mov ah, 3fh ; restore AX (doscall trashes it)
  921. DOSCALL ; read second 32K
  922. jc saerr
  923. cmp ax, cx
  924. jnz saerr
  925. jmp short sa_zero_fill_rest
  926. not_huge_read:
  927. DOSCALL
  928. sa_iter_done:
  929. jc saerr ; Continue if no errors
  930. cmp ax,cx ; Read ok, did we get what we asked for?
  931. jne saerr ; No, fail
  932. test es:[si].ns_flags,NSRELOC ; Relocation records?
  933. jz sa_zero_fill_rest ; No, continue
  934. mov ax, ds:[di] ; Extra word was read here
  935. mov OFF_prleinfo, ax
  936. jmps sa_zero_fill_rest
  937. saerr:
  938. pop ds
  939. pop si
  940. pop es
  941. mov ax, -1 ; File error
  942. jmp sax
  943. if ROM
  944. sa_exp_seg:
  945. xor si,si
  946. mov es,pseg
  947. ;; NOT Compiled for WOW
  948. call get_rover_2
  949. cCall LZDecode,<es,bx,si,si>
  950. mov di,ax
  951. or ax,ax
  952. jnz sa_zero_fill_rest
  953. if KDEBUG
  954. Debug_Out "LZDecode of segment failed!"
  955. endif
  956. pop ds
  957. pop si
  958. pop es
  959. jmp sax
  960. endif
  961. sa_zero_fill_rest: ; di == bytes written so far
  962. GETSEGLEN pseg ; seg len to ax, 0 == 64K
  963. sub ax,di ; Any uninitialized portion?
  964. jz sa_after_read ; No, continue
  965. ifdef WOW_x86;
  966. .386
  967. ;; WOW we don't want to call NT to set the selector
  968. push ax
  969. cCall get_physical_address,<psegdest>
  970. shl edx,16
  971. mov dx,ax
  972. mov ax,FLAT_SEL
  973. mov es,ax
  974. and edi,0000ffffh
  975. add edi,edx ; es:edi -> pseg:0
  976. pop cx
  977. push edx
  978. xor eax,eax
  979. cld
  980. mov dx,cx
  981. shr cx, 2
  982. movzx ecx,cx
  983. rep stos dword ptr [edi]
  984. mov cx, dx
  985. and cx, 3
  986. rep stos byte ptr [edi]
  987. pop edx
  988. sub edi,edx
  989. else
  990. mov es,psegdest ; Yes, set it to zero
  991. call get_rover_2
  992. mov cx,ax
  993. xor ax,ax
  994. cld
  995. shr cx, 1
  996. rep stosw
  997. adc cx, cx
  998. rep stosb
  999. endif
  1000. sa_after_read:
  1001. les si, pseginfo
  1002. if LDCHKSUM
  1003. mov ds,psegdest
  1004. xor si,si
  1005. mov cx,di
  1006. shr cx,1
  1007. xor dx,dx
  1008. cld
  1009. sa5b:
  1010. lodsw
  1011. xor dx,ax
  1012. loop sa5b
  1013. endif
  1014. cmp pleaseNoLock, 0
  1015. jnz dont_patch
  1016. push dx
  1017. cCall <far ptr PatchCodeHandle>,<hseg>
  1018. pop dx
  1019. dont_patch:
  1020. pop ds ; Restore DS
  1021. pop si ; segment info pointer
  1022. pop es
  1023. mov ax,es:[si].ns_flags ; Are we loading a code segment?
  1024. and ax,NSDATA
  1025. .errnz NSCODE
  1026. jnz sa9
  1027. ; Here when loading a code segment
  1028. if LDCHKSUM
  1029. mov cx,segno
  1030. dec cx
  1031. shl cx,1
  1032. shl cx,1
  1033. mov di,es:[ne_psegcsum]
  1034. add di,cx
  1035. mov cx,dx
  1036. xchg es:[di],cx
  1037. jcxz sa6a0
  1038. cmp cx,dx
  1039. je sa6a0
  1040. dec retry
  1041. jl sa6a1
  1042. public badsegread
  1043. badsegread:
  1044. mov ah,0Dh ; Disk Reset
  1045. DOSCALL
  1046. jmp sareread
  1047. sa6a1:
  1048. krDebugOut DEB_ERROR, "Segment contents invalid %es2"
  1049. xor ax,ax
  1050. jmps sax
  1051. sa6a0:
  1052. mov word ptr es:[di+2],0
  1053. endif
  1054. sa9:
  1055. mov dx,SEG_prleinfo
  1056. mov cx,OFF_prleinfo
  1057. mov bx,hseg
  1058. mov ax,pseg
  1059. sax: or ax,ax
  1060. cEnd
  1061. .286
  1062. ;-----------------------------------------------------------------------;
  1063. ; iterated_data_seg
  1064. ;
  1065. ; This expands out iterated data segments (specifically for the
  1066. ; OS/2 m.exe). Due to the late date this is being sleazed in
  1067. ; instead of being done right. To be done right, the read would
  1068. ; go into the last part of the present block, and expanded in place,
  1069. ; the stack used for the next record count because the last record
  1070. ; never fits.
  1071. ;
  1072. ; Entry:
  1073. ; CX = number of bytes to read
  1074. ; DS:DX = place to put them
  1075. ; DS:DI = place where #relocs will magically appear
  1076. ; ES:SI = module exe header:seg info
  1077. ;
  1078. ; Returns:
  1079. ; CF = 1
  1080. ; DS:DI = updated magic place where #relocs will magically appear
  1081. ;
  1082. ; Error Return:
  1083. ; CX = 0
  1084. ;
  1085. ; Registers Destroyed:
  1086. ;
  1087. ; History:
  1088. ; Sun 28-Jan-1990 12:25:02 -by- David N. Weise [davidw]
  1089. ; Wrote it!
  1090. ;-----------------------------------------------------------------------;
  1091. assumes ds,nothing
  1092. assumes es,nothing
  1093. cProc iterated_data_seg,<PUBLIC,NEAR>,<bx,dx,si,ds,es>
  1094. localW temp_buf
  1095. localW freloc
  1096. cBegin
  1097. ; deal with that extra relocation word!
  1098. xor ax,ax
  1099. test es:[si].ns_flags,NSRELOC ; Relocation records?
  1100. jz @F
  1101. inc ax
  1102. @@: mov freloc,ax
  1103. ; first get a temp buffer
  1104. push bx
  1105. push cx
  1106. cCall IGlobalAlloc,<0,0,cx>
  1107. mov temp_buf,ax
  1108. pop cx
  1109. pop bx
  1110. or ax,ax
  1111. stc ; assume failure
  1112. jz ids_exit
  1113. push dx
  1114. push ds
  1115. ; read into the temp buffer
  1116. mov ds,ax
  1117. xor dx,dx
  1118. mov ah,3Fh
  1119. DOSCALL
  1120. pop ds
  1121. pop dx
  1122. jc ids_exit1
  1123. cmp ax,cx
  1124. jnz ids_exit1
  1125. ; expand the buffer, yes we should special case strings of length 1
  1126. cmp freloc,0 ; was an extra word read?
  1127. jz @F
  1128. sub cx,2
  1129. @@: mov dx,cx
  1130. smov es,ds
  1131. xor di,di
  1132. mov ds,temp_buf
  1133. xor si,si
  1134. cld
  1135. ids_next_group:
  1136. lodsw ; get the # interations
  1137. mov cx,ax
  1138. lodsw ; get the # bytes
  1139. @@: push cx
  1140. push si
  1141. mov cx,ax
  1142. rep movsb
  1143. pop si
  1144. pop cx
  1145. loop @B
  1146. add si,ax ; get past group
  1147. cmp si,dx
  1148. jb ids_next_group
  1149. ; data segment now processed, deal with reloc word
  1150. cmp freloc,0 ; was an extra word read?
  1151. jz @F
  1152. movsw
  1153. sub di,2
  1154. add dx,2
  1155. @@: mov ax,dx
  1156. mov cx,dx
  1157. clc
  1158. ids_exit1:
  1159. pushf ; preserve the carry flag
  1160. push ax
  1161. push cx
  1162. smov ds,0
  1163. cCall IGlobalFree,<temp_buf>
  1164. pop cx
  1165. pop ax
  1166. popf
  1167. ids_exit:
  1168. cEnd
  1169. ;-----------------------------------------------------------------------;
  1170. ; PatchCodeHandle ;
  1171. ; ;
  1172. ; Patches the prologs of the procedures in the given code segment. ;
  1173. ; ;
  1174. ; Arguments: ;
  1175. ; parmW hseg ;
  1176. ; ;
  1177. ; Returns: ;
  1178. ; AX = hseg ;
  1179. ; DX = pseg ;
  1180. ; ;
  1181. ; Error Returns: ;
  1182. ; ;
  1183. ; Registers Preserved: ;
  1184. ; DI,SI,DS ;
  1185. ; ;
  1186. ; Registers Destroyed: ;
  1187. ; BX,CX,ES ;
  1188. ; ;
  1189. ; Calls: ;
  1190. ; MyLock ;
  1191. ; ;
  1192. ; History: ;
  1193. ; ;
  1194. ; Sun 17-Sep-1989 10:45:24 -by- David N. Weise [davidw] ;
  1195. ; Added support for symdeb to understand segments in himem. ;
  1196. ; ;
  1197. ; Tue Oct 27, 1987 06:19:12p -by- David N. Weise [davidw] ;
  1198. ; Added this nifty comment block. ;
  1199. ;-----------------------------------------------------------------------;
  1200. assumes ds,nothing
  1201. assumes es,nothing
  1202. cProc PatchCodeHandle,<PUBLIC,FAR>,<si,di>
  1203. parmW hseg
  1204. localW pseg
  1205. localW hexe
  1206. localW segno
  1207. localW segoffset
  1208. ifdef WOW_x86
  1209. .386
  1210. localD rover_2
  1211. endif
  1212. cBegin
  1213. SetKernelDS
  1214. cCall MyLock,<hseg>
  1215. mov pseg,ax ; Save physical addresss
  1216. or ax,ax ; All done if discarded
  1217. jz pcsDone1
  1218. xor si,si
  1219. mov segoffset, si
  1220. push ax
  1221. cCall GetOwner,<pseg>
  1222. mov es, ax
  1223. pop ax
  1224. cmp es:[si].ne_magic,NEMAGIC
  1225. if KDEBUG
  1226. jz good_boy
  1227. bad_boy:
  1228. krDebugOut DEB_ERROR "PatchCodeHandle, owner not NewExe %es2"
  1229. jmps pcsDone1
  1230. good_boy:
  1231. endif
  1232. jne pcsDone1
  1233. mov hexe,es
  1234. mov cx,es:[si].ne_cseg ; We need si to point to entry
  1235. mov si,es:[si].ne_segtab ; anyway so do it the slow way
  1236. pcsLoop:
  1237. cmp es:[si].ns_handle,dx ; Scan table for handle
  1238. je pcsFound
  1239. add si,SIZE NEW_SEG1
  1240. loop pcsLoop
  1241. pcsDone1:
  1242. jmp pcsDone
  1243. pcsExit1:
  1244. jmp pcsExit
  1245. pcsFound:
  1246. sub cx,es:[ne_cseg] ; Compute segment# from remainder
  1247. neg cx ; of loop count
  1248. inc cx ; 1-based segment#
  1249. mov segno,cx
  1250. test es:[si].ns_flags,NSDATA
  1251. jnz pcsExit1
  1252. .errnz NSCODE
  1253. push si
  1254. mov di,es:[ne_pautodata]
  1255. or di,di
  1256. jz sa6a
  1257. cCall MyLock,<es:[di].ns_handle>
  1258. mov di,ax
  1259. sa6a: ; DI:0 points to data segment (or 0)
  1260. ifdef WOW_x86
  1261. ;; For WOW we use the NT Magic data selector, since all 16 bit code is DATA
  1262. cCall get_physical_address,<pseg>
  1263. assumes es,nothing
  1264. shl edx,16
  1265. mov dx,ax ; ES:EDX -> pseg:0
  1266. mov rover_2,edx
  1267. mov ax,FLAT_SEL
  1268. mov es,ax
  1269. else
  1270. mov es,pseg ; ES:0 points to code segment
  1271. call get_rover_2
  1272. endif
  1273. mov ds,hexe ; DS:SI points to entry table
  1274. assumes ds,nothing
  1275. mov si,ds:[ne_enttab]
  1276. cld
  1277. or di, di ; Anything to do?
  1278. jz sa6x
  1279. sa6b:
  1280. lods word ptr ds:[si]
  1281. mov dx, ax
  1282. lods word ptr ds:[si]
  1283. sub ax, dx ; Get # entries in this block
  1284. or ax,ax
  1285. jz sa6x ; Done if zero
  1286. push word ptr ds:[si] ; Next block
  1287. add si, 2 ; Skip Next
  1288. mov cx,ax
  1289. sa6c:
  1290. mov al,ds:[si].pentsegno ; Get segment# from int instruction
  1291. cmp byte ptr segno,al ; Does this moveable segment match ES?
  1292. jne sa6e ; No, advance to next entry
  1293. ifdef WOW_x86
  1294. movzx ebx, word ptr ds:[si].pentoffset ; Get entry point offset
  1295. add ebx,rover_2
  1296. mov al, ds:[si].pentflags ; Get entry point flags
  1297. cmp byte ptr es:[ebx+2],90h ; Yes, followed by nop?
  1298. jne sa6e ; No, can;t patch prolog then
  1299. cmp word ptr es:[ebx],0581Eh ; Is it a push ds, pop ax?
  1300. jne @F ; Yes, take care of prolog
  1301. mov word ptr es:[ebx],0D88Ch
  1302. jmps sa6d1
  1303. @@:
  1304. cmp word ptr es:[ebx],0D88Ch ; Is it a mov ax,ds?
  1305. jne sa6e ; No, can't patch prolog then
  1306. sa6d1:
  1307. test al,ENT_DATA ; Valid prolog. shared data?
  1308. jnz sa6d2 ; Yes, patch mov ax,DGROUP into prolog
  1309. test byte ptr ds:[ne_flags],NEINST ; No, multiple instances?
  1310. jz sa6e ; No, do nothing
  1311. test al,ENT_PUBLIC ; Public entry point?
  1312. jz sa6e ; No, do nothing
  1313. mov word ptr es:[ebx],09090h ; Yes, set nop, nop in prolog
  1314. jmps sa6e
  1315. sa6d2:
  1316. mov byte ptr es:[ebx],0B8h ; Set mov ax,
  1317. mov es:[ebx+1],di ; DGROUP
  1318. else ; NOT WOW_x86
  1319. mov bx, ds:[si].pentoffset ; Get entry point offset
  1320. mov al, ds:[si].pentflags ; Get entry point flags
  1321. cmp byte ptr es:[bx+2],90h ; Yes, followed by nop?
  1322. jne sa6e ; No, can;t patch prolog then
  1323. cmp word ptr es:[bx],0581Eh ; Is it a push ds, pop ax?
  1324. jne @F ; Yes, take care of prolog
  1325. mov word ptr es:[bx],0D88Ch
  1326. jmps sa6d1
  1327. @@:
  1328. cmp word ptr es:[bx],0D88Ch ; Is it a mov ax,ds?
  1329. jne sa6e ; No, can't patch prolog then
  1330. sa6d1:
  1331. test al,ENT_DATA ; Valid prolog. shared data?
  1332. jnz sa6d2 ; Yes, patch mov ax,DGROUP into prolog
  1333. test byte ptr ds:[ne_flags],NEINST ; No, multiple instances?
  1334. jz sa6e ; No, do nothing
  1335. test al,ENT_PUBLIC ; Public entry point?
  1336. jz sa6e ; No, do nothing
  1337. mov word ptr es:[bx],09090h ; Yes, set nop, nop in prolog
  1338. jmps sa6e
  1339. sa6d2:
  1340. mov byte ptr es:[bx],0B8h ; Set mov ax,
  1341. mov es:[bx+1],di ; DGROUP
  1342. endif; WOW_x86
  1343. sa6e:
  1344. add si,SIZE PENT ; Advance to next entry in
  1345. loop sa6c ; this block
  1346. pop si
  1347. or si, si
  1348. jnz sa6b
  1349. sa6x:
  1350. mov es,hexe
  1351. pop si
  1352. pcsExit:
  1353. or byte ptr es:[si].ns_flags,NSLOADED ; Mark segment as loaded
  1354. ;;;if SDEBUG ; Tell debugger about new segment
  1355. ;;; mov bx,es:[ne_restab]
  1356. ;;; inc bx
  1357. ;;; mov dx,es:[si].ns_flags
  1358. ;;; mov ax,segoffset ; tell symdeb how to fixup symbols
  1359. ;;; test dx,NSDATA ; test to pass NSKCACHED too
  1360. ;;; jz sa8
  1361. ;;; test byte ptr es:[ne_flags],NEINST
  1362. ;;; jz sa8
  1363. ;;; mov ax,es:[ne_usage]
  1364. ;;; dec ax
  1365. ;;;sa8:
  1366. ;;; mov cx,segno
  1367. ;;; dec cx
  1368. ;;; cCall DebugDefineSegment,<esbx,cx,pseg,ax,dx>
  1369. ;;;endif
  1370. pcsDone:
  1371. mov ax,hseg
  1372. mov dx,pseg
  1373. cEnd
  1374. sEnd CODE
  1375. externFP FarAllocSeg
  1376. externFP FarMyAlloc
  1377. externFP FarMyAllocLinear
  1378. externFP FarMyFree
  1379. externFP FarSetOwner
  1380. sBegin NRESCODE
  1381. assumes CS,NRESCODE
  1382. assumes DS,NOTHING
  1383. assumes ES,NOTHING
  1384. externNP MapDStoDATA
  1385. externA __AHINCR
  1386. ;-----------------------------------------------------------------------;
  1387. ; AllocAllSegs ;
  1388. ; ;
  1389. ; "Allocates" for all segments of the module being loaded and stores ;
  1390. ; the addresses in the segment table. By allocate we mean: ;
  1391. ; ;
  1392. ; AUTOMATIC DATA gets space, but not yet loaded, ;
  1393. ; PRELOAD FIXED get global mem allocated , but not yet loaded, ;
  1394. ; MOVEABLE get a handle for later use, ;
  1395. ; FIXED get nothing. ;
  1396. ; ;
  1397. ; If this is not the first instance, then just allocate space for ;
  1398. ; the new instance of the automatic data segment. ;
  1399. ; ;
  1400. ; Arguments: ;
  1401. ; parmW hexe ;
  1402. ; ;
  1403. ; Returns: ;
  1404. ; ;
  1405. ; Error Returns: ;
  1406. ; AX =-1 not enough memory ;
  1407. ; ;
  1408. ; Registers Preserved: ;
  1409. ; ;
  1410. ; Registers Destroyed: ;
  1411. ; ;
  1412. ; Calls: ;
  1413. ; FarAllocSeg ;
  1414. ; FarMyAlloc ;
  1415. ; FarMyFree ;
  1416. ; ;
  1417. ; History: ;
  1418. ; ;
  1419. ; Tue Feb 24, 1987 01:04:12p -by- David N. Weise [davidw] ;
  1420. ; Added this nifty comment block. ;
  1421. ;-----------------------------------------------------------------------;
  1422. cProc AllocAllSegs,<NEAR,PUBLIC>,<si,di,ds>
  1423. parmW hexe
  1424. localW cSegs
  1425. localD hugeLen ; cum length of huge segment
  1426. localW hugeIndex ; index of first segment of huge
  1427. localW hugeOffs ; offset of first segment desc of huge
  1428. localW hugeCnt ; segments making up huge seg
  1429. localW hugeFlags ; flags of huge segment (needed?)
  1430. cBegin
  1431. call MapDStoDATA
  1432. ReSetKernelDS
  1433. mov es,hexe
  1434. mov si,es:[ne_segtab]
  1435. xor di,di
  1436. mov cSegs,di
  1437. inc di
  1438. cmp es:[ne_usage],di
  1439. je paloop
  1440. mov si,es:[ne_pautodata]
  1441. and byte ptr es:[si].ns_flags,not NSALLOCED+NSLOADED
  1442. mov di,es:[si].ns_handle
  1443. cCall FarAllocSeg,<essi>
  1444. or ax,ax
  1445. jz aa_nomem
  1446. inc cSegs
  1447. outahere:
  1448. jmp pagood
  1449. aa_nomem:
  1450. mov es,hexe
  1451. or byte ptr es:[si].ns_flags,NSALLOCED+NSLOADED
  1452. mov es:[si].ns_handle,di
  1453. jmp pafail3
  1454. paloop:
  1455. cmp di,es:[ne_cseg]
  1456. jbe more_to_go
  1457. jmp pagood
  1458. more_to_go:
  1459. mov bx,es:[si].ns_flags
  1460. test bl,NSPRELOAD ; Are we preloading?
  1461. jz not_preload
  1462. test bl,NSDATA ; Preload data although moveable
  1463. jnz paalloc
  1464. if ROM
  1465. test bh,(NSINROM SHR 8) ; Segment in ROM?
  1466. jz @f
  1467. test bl,NSLOADED ; Yes, is it already 'loaded'?
  1468. jnz set_rom_owner ; Yes, just need to set owner
  1469. @@:
  1470. endif
  1471. test bl,NSMOVE ; Fixed segment?
  1472. jz paalloc ; Yes, allocate segment
  1473. not_preload:
  1474. if ROM
  1475. test bh,(NSINROM SHR 8) ; Segment in ROM?
  1476. jz @f
  1477. if KDEBUG
  1478. test bl,NSDATA ; (non-preload data segments in ROM
  1479. jz not_rom_data ; haven't been tested)
  1480. int 3
  1481. not_rom_data:
  1482. endif
  1483. test bl,NSLOADED ; Yes, already 'loaded'?
  1484. jnz set_rom_owner ; Yes, just need to set owner
  1485. @@:
  1486. endif
  1487. test bl,NSALLOCED ; Already allocated?
  1488. jnz panext ; Yes, then nothing to do
  1489. test bl,NSMOVE ; Fixed segment?
  1490. jz panext ; Yes, then nothing to do
  1491. xor cx,cx ; No, allocate zero length
  1492. push es ; object so that we guarantee
  1493. cCall FarMyAlloc,<bx,cx,cx> ; we will have a handle.
  1494. pop es
  1495. or dx,dx ; Fail if we cant get a handle
  1496. jz pafail
  1497. if ROM
  1498. ; If this segment gets loaded from ROM, change the segment handle
  1499. ; to be the one that was used to fix-up the ROM code segments. This
  1500. ; is the value of ns_sector in the segment table.
  1501. test byte ptr es:[si].ns_flags+1,(NSINROM SHR 8)
  1502. jz not_a_rom_seg
  1503. mov bx,es:[si].ns_sector
  1504. test dl,GA_FIXED
  1505. jnz sa_fixed
  1506. StoH bx
  1507. sa_fixed:
  1508. cCall ChangeROMHandle,<dx,bx>
  1509. mov dx,bx
  1510. not_a_rom_seg:
  1511. endif
  1512. mov es:[si].ns_handle,dx ; Handle into seg table
  1513. and byte ptr es:[si].ns_flags,not NSLOADED
  1514. or byte ptr es:[si].ns_flags,NSALLOCED
  1515. mov bx,dx ; put handle into base register
  1516. call set_discarded_sel_owner
  1517. jmps panext
  1518. if ROM
  1519. set_rom_owner:
  1520. cCall FarSetROMOwner,<es:[si].ns_handle,es>
  1521. jmps panext
  1522. endif
  1523. paalloc:
  1524. cmp es:[si].ns_minalloc, 0
  1525. jnz paalloc_fer_shure
  1526. jmps PAHugeAlloc
  1527. paalloc_fer_shure:
  1528. cCall FarAllocSeg,<essi>
  1529. or ax,ax
  1530. jz pafail
  1531. inc cSegs
  1532. panext:
  1533. add si,size NEW_SEG1
  1534. inc di
  1535. jmp paloop
  1536. ; only gets here if not enough memory, free up all previous segments
  1537. pafail:
  1538. mov si,es:[ne_segtab]
  1539. mov cx,es:[ne_cseg]
  1540. pafail1:
  1541. push cx
  1542. mov cx,es:[si].ns_handle
  1543. jcxz pafail2
  1544. push es
  1545. ;Need to handle freeing huge segments!!!
  1546. cCall FarMyFree,<cx>
  1547. pop es
  1548. mov es:[si].ns_handle, 0 ; Necessary for EntProcAddress
  1549. pafail2:
  1550. and byte ptr es:[si].ns_flags,not (NSALLOCED+NSLOADED)
  1551. add si,size NEW_SEG1
  1552. pop cx
  1553. loop pafail1
  1554. pafail3:
  1555. mov cSegs,-1
  1556. jmp pagood
  1557. PAHugeAlloc:
  1558. ; at this point, es:si -> current seg record
  1559. ; di is segment index (range from 1 to es:[ne_cseg])
  1560. mov off_hugeLen, 0
  1561. mov seg_hugeLen, 0 ; init length to 0K
  1562. mov hugeOffs, si
  1563. mov hugeCnt, 1
  1564. mov ax, es:[si].ns_flags
  1565. or ax, NSHUGESEG
  1566. mov hugeFlags, ax
  1567. PAHugeLoop:
  1568. mov ax, es:[si].ns_minalloc ; add current segment to group
  1569. cmp ax, 1
  1570. sbb dx, dx
  1571. neg dx
  1572. add off_hugeLen, ax
  1573. adc seg_hugeLen, dx
  1574. or es:[si].ns_flags, NSHUGESEG
  1575. cmp es:[si].ns_minalloc, 0 ;
  1576. jnz PAHugeEndLoop
  1577. cmp di, es:[ne_cseg]
  1578. jae PAHugeEndLoop
  1579. mov ax, si
  1580. add ax, size NEW_SEG1
  1581. cmp ax, es:[ne_pautodata]
  1582. jz PAHugeEndLoop
  1583. mov ax, hugeFlags ; do flags have to be identical?
  1584. cmp ax, es:[si].ns_flags
  1585. jnz PAHugeEndLoop
  1586. inc hugeCnt
  1587. inc di
  1588. add si, size NEW_SEG1
  1589. jmp PAHugeLoop
  1590. PAHugeEndLoop:
  1591. inc di
  1592. push es
  1593. or hugeFlags, NSMOVE
  1594. cCall FarMyAllocLinear, <hugeFlags, hugeLen>
  1595. pop es
  1596. or ax, ax ; check for error
  1597. jnz Not_pafail
  1598. jmp pafail
  1599. Not_pafail:
  1600. mov si, hugeOffs ; fix up segment(s)
  1601. and es:[si].ns_flags, NOT NSHUGESEG
  1602. PAHugeSegLoop:
  1603. mov es:[si].ns_handle, dx
  1604. and byte ptr es:[si].ns_flags, not NSLOADED
  1605. or byte ptr es:[si].ns_flags, NSALLOCED
  1606. cCall FarSetOwner, <ax, es>
  1607. add si, size NEW_SEG1
  1608. add dx, __AHINCR
  1609. dec hugeCnt
  1610. jnz PAHugeSegLoop
  1611. ; continue with rest of allocations
  1612. jmp paloop
  1613. pagood:
  1614. mov ax,cSegs
  1615. cEnd
  1616. sEnd NRESCODE
  1617. end