From: mouse@thunder.mcrcim.mcgill.edu (der Mouse)
Subject: Re: What is text, data & bss anyway?
Organization: McGill Research Centre for Intelligent Machines
Date: Fri, 18 Dec 92 01:21:16 GMT

In article <1992Dec14.234221.6644@saifr00.cfsat.honeywell.com>, klaus@saifr00.cfsat.honeywell.com (Todd Klaus) writes:

> My collegues and I are experiencing some confusion as to the exact
> definition of the text, data and bss segments of a executable image
> on disk and how this changes when it is loaded into core memory.

(If we're going to be talking about "exact definitions", then perhaps
"core memory" is not the best term to use :-)

> My understanding (simplistic) is that the text segment is executable
> instructions, data is initialized data, and bss is uinitialized data.

This is roughly correct; however, the the bss segment is, in most
machines now filled with all 0 bits rather than unspecified contents.
Also, the text segment contains things other than executable
instructions.  Some compilers put string literals there, and anything
read-only can go there, though on most systems there is no way to put
anything but code (and sometimes, string literals) there from C.

When an executable file is run, text and data segments are set up.  The
text segment from the file becomes the text segment in-core; the
in-core data segment is the data+bss from the file, with bss cleared to
zeroes.  A third segment exists at run-time, the stack segment, which
is set up by the system, typically containing the environment and argv
strings and an initial stack frame or two to call main().

> Could someone please show me a code fragment showing what types of
> variables would fall into each category?

Variables do not normally go into the text segment.  All the discussion
below refers to the following:

	int foo = 5;
	static int bar;
	static float blee;
	static char *bloop;
	int baz;

Normally, foo will go in the data segment and bar in bss.  (I assume,
of course, the absence of a later "static int bar = 12;", which would
make the compiler put bar into the data segment.)

blee and bloop can go in bss if, and only if, all-0-bits is
floating-point zero (for blee) or nil-pointer-to-char (for bloop).  (Of
course, even if this isn't the case, the compiler is at liberty to put
them in bss anyway, provided it arranges for them to be set to the
correct initial values before they can first be accessed.  This is true
of any variable that would normally go in data.)

baz is a more interesting case.  Most systems use one of two models for
such variables: the def/ref model and the common model.  (Either one is
permitted by ANSI C.)  In the def/ref model, exactly one such
definition must appear in the program for baz; all other references
must declare it as extern.  In the common model, multiple files may
declare baz as above, and at most one of them may declare it with an
initial value (such as was done for foo).  Additional files may declare
it with extern.  A common-model linker is then responsible for
determining whether there is an initialized instance of baz, and if so,
effectively turning all the other references into externs; if not, it
will allocate space in bss for it.

> As an aside, does copy-on-write have anything to do with this scheme?

Only as a plausible method of implementation.  The run-time text and
data might, for example, be set up by mapping the text and data from
the file into memory, with the text read-only and the data c-o-w.  (The
bss would normally be set up as demand-zero pages, so that real memory
isn't allocated until it's needed, for faster startup.)

					der Mouse

			    mouse@larry.mcrcim.mcgill.edu
Newsgroups: comp.unix.wizards