Xref: utzoo comp.unix.wizards:22819 comp.unix.i386:6675 Path: utzoo!attcan!lsuc!eci386!clewis From: clewis@eci386.uucp (Chris Lewis) Newsgroups: comp.unix.wizards,comp.unix.i386 Subject: Re: Implementing NULL trapping on AT&T SVR3.2(.2) Message-ID: <1990Jul10.172556.24711@eci386.uucp> Date: 10 Jul 90 17:25:56 GMT References: <412@minya.UUCP> <13291@smoke.BRL.MIL> <1990Jul5.174608.17336@eci386.uucp> <1990Jul6.115941.11096@cbnews.att.com> Reply-To: clewis@eci386.UUCP (Chris Lewis) Organization: Elegant Communications Inc. Lines: 78 I've come up with a partial (non-generalized) solution to implementing NULL dereference catching... (Incidentally, you changed the subject to SVR3.2[.2] - we're 386/ix 1.0.6 which is SVR3.0, but I think my partial solution will still work on SVR3.2) In article pcg@cs.aber.ac.uk (Piercarlo Grandi) writes: | In article <1990Jul5.174608.17336@eci386.uucp> clewis@eci386.UUCP | (Chris Lewis) writes: |>On System V (I'm 386/ix 1.0.6), the memory layout of an executable |>program is controlled by a default loader control file ("ifile"), |> ... |>386 one uses the "defaults" built into "ld"'s binary, which I can't |>seem to be able to reconstruct from the 386/ix Guide entries for |>the loader. | You cannot. The example assumes a linker primtive that is not actually | there. This one is the one that tells you how long is the COFF header; | without this you must waste almost a pageful in the executable... I managed to construct an ifile that does almost what I want: >SECTIONS >{ > .text 0xd0 : { *(.init) *(.text) *(.fini) } > GROUP BIND ( NEXT(0x400000) + > ((SIZEOF(.text) + ADDR(.text)) % 0x2000)) : > { > .data : { } > .bss : { } > } >} The 0xd0 is in replacement of the "sizeof_headers" primitive that's missing according to the Guide (p 12-14). The 0xd0 is formed by computing: sizeof(struct filehdr) + sizeof(struct aouthdr) + 4 * sizeof(struct scnhdr) The 4 is the number of sections that dump -h tells you about when you link without the ifile (.text/.data/.bss/.comment). If you use shared libraries in your link (-lc_s), this number goes to 7 (constant becomes 0x148). These constants may be slightly different on your machine - you'll have to figure out how big filehdr,aouthdr,scnhdr and run the loader without an ifile to figure out how many sections would be in the output file. [Explanation: link .init/.text/.fini at 0xd0, link .data and .bss contiguously starting at 0x400000, with the same starting offset within a page as the end of the .text area - the 0x400000 is the "region" according to the SAMS book where data is supposed to go.]. If you change the 0x00d0 to 0x10d0 or 0x20d0 or 0x30d0 etc., page 0 is not mapped into memory and the program will fault on a null-dereference. Yeah! What I still cannot do is make this ifile independent of the size of the headers.... It appears as if the loader(kernel?) automatically prepends the headers to the output .text section in the executing image, and you have to get the offset of the .text section to be equal to the sizeof of the headers if you want the resultant "virtual" .text to start at a offset of 0 within a page. If I set the constant to 0x20d0, virtual address 0x2000 has the filehdr magic number again.... | That is pretty easy. All you have to do is to read as a preliminary the | Unix Papers (SAMS) article on the port of System V to the 386, as there | are a couple of non obvious tricks: you must make the data begin at the | same within the page offset where the code ends, and you must make the | code begin -- within the loadable file itself -- at a page boundary. I borrowed a copy, and it wasn't too helpful - too high a level to mention that file headers get automatically prepended to the .text area and it's the file headers that must start at a page boundary... Thank you Piercarlo for getting me onto the right track. -- Chris Lewis, Elegant Communications Inc, {uunet!attcan,utzoo}!lsuc!eci386!clewis Ferret mailing list: eci386!ferret-list, psroff mailing list: eci386!psroff-list