Hi folks,
I understood that Gary Oliver's shared text upgrade was only useful for
programs compiled with separate I&D (hence the frequent questions about
why the gcc port doesn't support separate I&D). If I am wrong in assuming
this then you can disregard the rest of this letter.
I run Minix-386 with a few minor kernel/fs patches on a 2MB 386SX
machine. Having successfully compiled bash (Bourne Again Shell - from
GNU) I was a might annoyed that I couldn't execute the simplest pipeline
because the wasn't enough contiguous memory for bash to fork twice (or
three times, or whatever........). So I thought about Gary's shared text
upgrade.
A couple of nights ago I installed these patches and everything came up
nicely. Admittedly I had to patch my PH1.5 version of ps (BTW, those of
you still labouring with ps/mu incompatibilities, I'm thinking about
posting my working versions with a nice clear description of what's going
on - any takers?).
Time for a test I thought, and forked a new copy of bash on top of the
running one. I didn't run out of memory, and mu reported two users of the
text area. Great I thought, except that my bcc compiled bash executable
has combined I & D. So how the hell did I manage to get a shared text
^^^^^^^^
segment? Not that I mind, but I'm mystified.
Can anybody explain this. Does anybody else use the shared-text upgrade
with Minix-386? Are there any good reasons why I shouldn't?
Thank's in advance.
Andy Walker.
bad...@cray.sintef.no |
Kvaerner Engineering a.s. | "It's not easy being a dolphin"
1324 Lysaker, Norway. |
P.S. Is there anybody out there who uses my kernel patches for
international keyboards? Is there anybody who's heard of them? Just
curious y'know 'cause I've never read any feedback.
Hi Guys,
A couple of days ago I posted a question about Minix-386 and Gary
Oliver's shared text upgrade. I haven't had a chance to read the replies
yet but I solved it myself.
1) I didn't know that bcc uses separate I & D by default. You need -i- to
turn it off (not -i to turn it on).
2) The reason I'd never known this is because 1.5.10 file(1) gets it
wrong when looking at 32 bit binaries. It thinks they're all combined.
Therefore, all my programs are actually separate I & D, and can take
advantage of shared text segments.
Rather than fixing 1.5.10's file(1) I decided to look at the version from
1.6.16. This version is much more flexible (it recognizes many more file
types). However, it still screws up on combined/separate I & D for 32 bit
binaries. It reports combined as separate and vice versa.
Below are two shar's. The first contains a cdiff against 1.6.16 file.c to
compile with regular 1.5.10 (ACK or BCC) headers, and to fix the bug
mentioned above. The second contains the full cdiff against 1.5.10 file.c
in case you didn't get (or want) the 1.6.16 upgrade posting. Again it
compiles with ACK/BCC and has the bug fixed.
Yours,
Andy Walker - bad...@cray.sintef.no
--------- Cut here if you've got the 1.6.16 patch ---------------------------
echo x - file.cdif
sed '/^X/s///' > file.cdif << '/'
X*** file.c~ Wed Oct 23 19:21:36 1991
X--- file.c Wed Oct 23 18:39:33 1991
X***************
X*** 7,12 ****
X--- 7,13 ----
X #include <fcntl.h>
X #include <stdlib.h>
X #include <stdio.h>
X+ #undef NULL /* AJW - else redefined from stdio.h */
X #include <unistd.h>
X
X #define XBITS 00111 /* rwXrwXrwX (x bits in the mode) */
X***************
X*** 45,53 ****
X "MINIX-PC 16-bit executable combined I & D space",
X 0x04, 0x01, 0x01, 0x03, 0x20, 0x04,
X "MINIX-PC 16-bit executable separate I & D space",
X- 0x04, 0x01, 0x01, 0x03, 0x20, 0x10,
X- "MINIX-PC 32-bit executable combined I & D space",
X 0x04, 0x01, 0x01, 0x03, 0x10, 0x10,
X "MINIX-PC 32-bit executable separate I & D space",
X 0x04, 0x01, 0x04, 0x10, 0x03, 0x01,
X "MINIX-68k executable",
X--- 46,54 ----
X "MINIX-PC 16-bit executable combined I & D space",
X 0x04, 0x01, 0x01, 0x03, 0x20, 0x04,
X "MINIX-PC 16-bit executable separate I & D space",
X 0x04, 0x01, 0x01, 0x03, 0x10, 0x10,
X+ "MINIX-PC 32-bit executable combined I & D space",
X+ 0x04, 0x01, 0x01, 0x03, 0x20, 0x10,
X "MINIX-PC 32-bit executable separate I & D space",
X 0x04, 0x01, 0x04, 0x10, 0x03, 0x01,
X "MINIX-68k executable",
/
--------- Cut here if you've got the 1.6.16 patch ---------------------------
--------- Cut here if you're patching from 1.5.10 ---------------------------
echo x - file.cdif
sed '/^X/s///' > file.cdif << '/'
X*** file.c~ Wed Oct 23 19:44:26 1991
X--- file.c Wed Oct 23 18:39:33 1991
X***************
X*** 1,26 ****
X /* file - report on file type. Author: Andy Tanenbaum */
X
X #include <blocksize.h>
X- #include <ar.h>
X #include <sys/types.h>
X #include <sys/stat.h>
X #include <fcntl.h>
X! #include <minix/config.h>
X
X- #if (CHIP == M68000)
X- #define A_OUT 0x410 /* magic number for executables */
X- #define A_OUT_SPLIT 0x420 /* magic number for executables split I/D */
X- #define A_OUT_SEC 0x301 /* second check for executables */
X- #define OBJECT 0x102 /* minix/st object */
X- #else
X- #define A_OUT 001401 /* magic number for executables */
X- #define SPLIT 002040 /* second word on split I/D binaries */
X- #endif
X #define XBITS 00111 /* rwXrwXrwX (x bits in the mode) */
X #define ENGLISH 25 /* cutoff for determining if text is Eng. */
X! char buf[BLOCK_SIZE];
X
X! main(argc, argv)
X int argc;
X char *argv[];
X {
X--- 1,71 ----
X /* file - report on file type. Author: Andy Tanenbaum */
X+ /* Magic number detection changed to look-up table 08-Jan-91 - ajm */
X
X #include <blocksize.h>
X #include <sys/types.h>
X #include <sys/stat.h>
X #include <fcntl.h>
X! #include <stdlib.h>
X! #include <stdio.h>
X! #undef NULL /* AJW - else redefined from stdio.h */
X! #include <unistd.h>
X
X #define XBITS 00111 /* rwXrwXrwX (x bits in the mode) */
X #define ENGLISH 25 /* cutoff for determining if text is Eng. */
X! unsigned char buf[BLOCK_SIZE];
X
X! struct info {
X! int match; /* No of bytes to match for success */
X! int execflag; /* 1 == ack executable, 2 == gnu executable */
X! unsigned char magic[4]; /* First four bytes of the magic number */
X! char *description; /* What it means */
X! } table[] = {
X! 0x03, 0x00, 0x1f, 0x9d, 0x8d, 0x00,
X! "13-bit compressed file",
X! 0x03, 0x00, 0x1f, 0x9d, 0x90, 0x00,
X! "16-bit compressed file",
X! 0x02, 0x00, 0x65, 0xff, 0x00, 0x00,
X! "MINIX-PC bcc archive",
X! 0x02, 0x00, 0x2c, 0xff, 0x00, 0x00,
X! "MINIX-68k ack archive",
X! 0x02, 0x00, 0x65, 0xff, 0x00, 0x00,
X! "MINIX-PC ack archive",
X! 0x04, 0x00, 0x47, 0x6e, 0x75, 0x20,
X! "MINIX-68k gnu archive",
X! 0x04, 0x00, 0x21, 0x3c, 0x61, 0x72,
X! "MINIX-PC gnu archive",
X! 0x02, 0x00, 0x01, 0x02, 0x00, 0x00,
X! "MINIX-68k ack object file",
X! 0x02, 0x00, 0xa3, 0x86, 0x00, 0x00,
X! "MINIX-PC bcc object file",
X! 0x04, 0x00, 0x00, 0x00, 0x01, 0x07,
X! "MINIX-68k gnu object file",
X! 0x04, 0x00, 0x07, 0x01, 0x00, 0x00,
X! "MINIX-PC gnu object file",
X! 0x04, 0x01, 0x01, 0x03, 0x10, 0x04,
X! "MINIX-PC 16-bit executable combined I & D space",
X! 0x04, 0x01, 0x01, 0x03, 0x20, 0x04,
X! "MINIX-PC 16-bit executable separate I & D space",
X! 0x04, 0x01, 0x01, 0x03, 0x10, 0x10,
X! "MINIX-PC 32-bit executable combined I & D space",
X! 0x04, 0x01, 0x01, 0x03, 0x20, 0x10,
X! "MINIX-PC 32-bit executable separate I & D space",
X! 0x04, 0x01, 0x04, 0x10, 0x03, 0x01,
X! "MINIX-68k executable",
X! 0x04, 0x02, 0x0b, 0x01, 0x00, 0x00,
X! "MINIX-PC 32-bit gnu executable combined I & D space",
X! 0x04, 0x02, 0x00, 0x00, 0x0b, 0x01,
X! "MINIX-68k gnu executable"
X! };
X!
X! int tabsize = sizeof(table) / sizeof(struct info);
X!
X! _PROTOTYPE(void main, (int argc, char **argv));
X! _PROTOTYPE(void file, (char *name));
X! _PROTOTYPE(void do_strip, (int type));
X! _PROTOTYPE(void usage, (void));
X!
X! void main(argc, argv)
X int argc;
X char *argv[];
X {
X***************
X*** 34,44 ****
X for (i = 1; i < argc; i++) file(argv[i]);
X }
X
X! file(name)
X char *name;
X {
X! int i, fd, n, magic, second, mode, nonascii, special, funnypct, etaoins;
X! int symbols;
X long engpct;
X char c;
X struct stat st_buf;
X--- 79,89 ----
X for (i = 1; i < argc; i++) file(argv[i]);
X }
X
X! void file(name)
X char *name;
X {
X! int i, fd, n, mode, nonascii, special, funnypct, etaoins;
X! int j, matches;
X long engpct;
X char c;
X struct stat st_buf;
X***************
X*** 75,139 ****
X close(fd);
X return;
X }
X! n = read(fd, buf, BLOCK_SIZE);
X if (n < 0) {
X printf("cannot read\n");
X close(fd);
X return;
X }
X!
X! /* Check to see if file is an archive. */
X! #if (CHIP == M68000)
X! magic = (buf[0] << 8) | (buf[1] & 0377);
X! if (magic == 026377) {
X! #else
X! magic = (buf[1] << 8) | (buf[0] & 0377);
X! if (magic == ARMAG) {
X! #endif
X! printf("archive\n");
X! close(fd);
X! return;
X! }
X! #if (CHIP == M68000)
X! /* Check to see if file is an object file. */
X! if (magic == OBJECT) {
X! printf("MINIX/ST object file\n");
X! close(fd);
X! return;
X! }
X! #endif
X!
X! /* Check to see if file is an executable binary. */
X! #if (CHIP != M68000)
X! if (magic == A_OUT) {
X! /* File is executable. Check for split I/D. */
X! printf("MINIX/PC executable");
X! second = (buf[3] << 8) | (buf[2] & 0377);
X! if (second == SPLIT)
X! printf(" separate I & D space");
X! else
X! printf(" combined I & D space");
X! #else
X! if (magic == A_OUT || magic == A_OUT_SPLIT) {
X! /* File is executable. Check for split I/D. */
X! printf("MINIX/ST executable");
X! second = (buf[2] << 8) | (buf[3] & 0377);
X! if (second == A_OUT_SEC) {
X! if (magic == A_OUT_SPLIT)
X! printf(" separate I & D space");
X! else
X! printf(" combined I & D space");
X! }
X! #endif
X! symbols = buf[28] | buf[29] | buf[30] | buf[31];
X! if (symbols != 0)
X! printf(" not stripped\n");
X! else
X! printf(" stripped\n");
X! close(fd);
X! return;
X }
X
X /* Check to see if file is a shell script. */
X if (mode & XBITS) {
X /* Not a binary, but executable. Probably a shell script. */
X--- 120,151 ----
X close(fd);
X return;
X }
X! n = read(fd, (char *)buf, BLOCK_SIZE);
X if (n < 0) {
X printf("cannot read\n");
X close(fd);
X return;
X }
X! if (n == 0) { /* must check this, for loop will fail otherwise !! */
X! printf("empty file\n");
X! close(fd);
X! return;
X! }
X!
X! for (i = 0; i < tabsize; i++) {
X! matches = 0;
X! for (j = 0; j < table[i].match; j++)
X! if (buf[j] == table[i].magic[j])
X! matches++;
X! if (matches == table[i].match) {
X! printf("%s", table[i].description);
X! do_strip(table[i].execflag);
X! close(fd);
X! return;
X! }
X }
X
X+
X /* Check to see if file is a shell script. */
X if (mode & XBITS) {
X /* Not a binary, but executable. Probably a shell script. */
X***************
X*** 178,184 ****
X return;
X }
X
X! usage()
X {
X printf("Usage: file name ...\n");
X exit(1);
X--- 190,218 ----
X return;
X }
X
X! void do_strip(type)
X! int type;
X! {
X! if (type == 1) { /* Non-GNU executable */
X! if (( buf[28] | buf[29] | buf[30] | buf[31]) != 0)
X! printf(" not stripped\n");
X! else
X! printf(" stripped\n");
X! return;
X! }
X!
X! if (type == 2) { /* GNU format executable */
X! if ((buf[16] | buf[17] | buf[18] | buf[19]) != 0)
X! printf(" not stripped\n");
X! else
X! printf(" stripped\n");
X! return;
X! }
X!
X! printf("\n"); /* Not an executable file */
X! }
X!
X! void usage()
X {
X printf("Usage: file name ...\n");
X exit(1);
/
--------- Cut here if you're patching from 1.5.10 ---------------------------
I have found a bug in the 1.6.16 version of dosread. I don't know if
this has been noticed before but I've not seen a fix for it.
There is a line which reads:
if((dev_nr = *argv[index++]) & 0x5f < 'A' || dev_nr & 0x5f > 'Z')
This is intended to check that the drive letter given lies in the
range 'A' to 'Z'. If the expression evaluates to true the program
exits with a usage message.
I have checked both editions of K&R (to make sure there are no
precedence differences between ANSI and K&R). Both state that the
comparison operators '<' and '>' have higher precedence than the
bitwise logical operators '&', '|' etc. This means that the above line
is evaluated as:
if ((dev_nr = *argv[index++]) & (0x5f < 'A') ||
dev_nr & (0x5f > 'Z'))
This is not quite what was intended. The net result is that 'B', 'D',
'F' etc are o.k. drive letters (and any other ascii char with bit 0
unset) whilst 'A', 'C', 'E' etc are rejected.
Change the line to read:
if(((dev_nr = *argv[index++]) & 0x5f) < 'A' || (dev_nr & 0x5f) > 'Z')
^ ^ ^ ^
for the desired effect.
Lets hope that this bug making it out onto the net was an oversight,
and not a symptom of a bug in somebody's ANSI (ACK) C compiler :-) .
BTW: What is the policy with the ANSI ACK compiler. Are the binaries
going to be posted to the net (made available for ftp). Of course the
sources wont be, but us net-folks are going to need this compiler (if
the 1.6.16 beta release was anything to go by). Otherwise we'll all
have to BUY new copies of Minix from PH when the ANSI compiler becomes
part of the package.
Andy.
------------------------------------------------------------------------
|bad...@cray.sintef.no | "I was neat, clean, shaved and sober |
| | and I didn't care who new it." |
|Andrew Walker, | |
|Stabekk, Norway. | Philip Marlowe - The Big Sleep |
------------------------------------------------------------------------
>I have found a bug in the 1.6.16 version of dosread. I don't know if
>this has been noticed before but I've not seen a fix for it.
I have noticed that bug and I am quite sure I posted it then (though I
am not sure if I sent it to comp.os.minix or to to beta-minix), but I
don't think I posted a bug-fix (my posting was more on the line of: Try
to find out what that line should do and then try to find out what it
really does :-).
[discussion of bug and consequences deleted...]
>Change the line to read:
> if(((dev_nr = *argv[index++]) & 0x5f) < 'A' || (dev_nr & 0x5f) > 'Z')
> ^ ^ ^ ^
>for the desired effect.
Why not just make it readable at the same time?
devnr = toupper (*argv [index ++]);
if (! isupper (devnr)) {
...
--
| _ | Peter J. Holzer | Think of it |
| |_|_) | Technical University Vienna | as evolution |
| | | | Dept. for Real-Time Systems | in action! |
| __/ | h...@vmars.tuwien.ac.at | Tony Rand |