[comp.sys.hp] HP-UX `ld' tricks.

irf@kuling.UUCP (Bo Thide') (11/05/90)

I am trying to speed up my linking and have played around with
the HP-UX 7.0 `ld' options "-X" and "-A". 
Questions:

1. The "-X <num>" option allows you to define the initial size for the linker's
   global symbol table.  This will reduce link time for very large
   programs.  Is there a clever way to set  <num> to maximize the speed-up?

2. The "-A name" option specifies incremental loading.  How would I
   use that in a makefile?  Are there any special "ld -A" tricks used
   by the HP-UX masters out there?

Bo

irf@kuling.UUCP (Bo Thide') (11/05/90)

I forgot to include my signature with the correct e-mail address and
new phone number (in case somebody would like to phone me the answers ..:-).

Bo

   ^   Bo Thide'--------------------------------------------------------------
  |I|       Swedish Institute of Space Physics, S-755 91 Uppsala, Sweden
  |R|  Phone: (+46) 18-303671.  Telex: 76036 (IRFUPP S).  Fax: (+46) 18-403100 
 /|F|\        INTERNET: bt@irfu.se       UUCP: ...!uunet!sunic!irfu!bt
 ~~U~~ -----------------------------------------------------------------sm5dfw

mjs@hpfcso.HP.COM (Marc Sabatella) (11/06/90)

>I am trying to speed up my linking and have played around with
>the HP-UX 7.0 `ld' options "-X" and "-A". 
>Questions:
>
>1. The "-X <num>" option allows you to define the initial size for the linker's
>   global symbol table.  This will reduce link time for very large
>   programs.  Is there a clever way to set  <num> to maximize the speed-up?

Sure.  Do the "ld" once, then run "nm | wc -l" to find out how many symbols
there are, and use that number.  Note the 800 also supports "-T" to use a
temporary file rather than memory to hold information; which could help in
particularly large links which thrash the VM system.  Most links, in my
experience, are I/O bound, so neither "-X" nor "-T" give huge improvements.

>2. The "-A name" option specifies incremental loading.  How would I
>   use that in a makefile?  Are there any special "ld -A" tricks used
>   by the HP-UX masters out there?

The "incremental loading" is a bit of a misnomer (as is the abbreviation "ld",
meaning "loader", for that matter).  The normal use of "-A" is for a running
program that wants to dynamically load (ie, malloc() up some memory and read(),
the execute code) an object file.  You couldn't normally execute code in an
object file loaded in this manner, because external references will not be
fully resolved, and the code will be assuming it will be loaded at address 0.

Thus a running program might malloc() some memory, then fork off a call to
"ld", then read the object in, and call routines within the loaded object.
The code would look something like this:

	#include <a.out.h>
	#include <nlist.h>

	/* allocate space for object */
	fp = fopen(objectname,"r");
	fread(&filhdr,sizeof(filhdr),1,fp);
	fclose(fp);
	size = filhdr.a_text + filhdr.a_data + filhdr.a_bss;
	addr = malloc(size);

	/* prepare object for loading */
	sprintf(cmdline,"ld -A %s -R %X %s",argv[0],addr,objectname);
	system(cmdline);

	/* read prepared object into memory */
	fp = fopen("a.out","r");
	fread(&filhdr,sizeof(filhdr),1,fp);
	fseek(fp,TEXTPOS,0);
	fread(addr,size,1,fp);
	fclose(fp);
	memset(addr+filhdr.a_text+filhdr.a_data,0,filhdr.a_bss);

	/* call entry points within it */
	nl[0].n_name = "entry0";
	nl[1].n_name = "entry1";
	nl[2].n_name = "entry2";
	nl[3].n_name = "";
	nlist("a.out",nl);
	entry0 = nl[0].n_value;
	entry1= nl[0].n_value;
	entry2 = nl[0].n_value;
	(*entry0)();
	(*entry1)();
	(*entry2)();

This is a bit of an oversimplification (and note how complicated it is already)
especially for the series 800, but it gives you the general idea of what "-A"
is there for.  It's most important function is to allow the "prepared" object
file to reference the running executable's own symbols; if this is not
necessary, then a simple "ld -R <addr>" would suffice.

In any case, this is probably not at all what you wanted, since you stated your
goal was to reduce link times.  "Incremental linking", that is, taking an
already linked a.out file, and an updated version of one of the .o files that
contributed to it, and somehow patch it in, is something different entirely.
It is not an a particularly easy task to do in full generality, as we have
discovered while trying to implement such a feature.

--------------
Marc Sabatella (marc@hpmonk.fc.hp.com)
Disclaimers:
	2 + 2 = 3, for suitably small values of 2
	Bill and Dave may not always agree with me

bla@hpcupt1.cup.hp.com (Brad Ahlf) (11/14/90)

> I am trying to speed up my linking and have played around with
> the HP-UX 7.0 `ld' options "-X" and "-A". 

For very large programs, you might have better luck speeding up your
links using the '-r' option to accomplish 'prelinks' with 'ld'.  This
could result in a lot less work for the linker to do when rebuilding
very large executables.

You could create a makefile setup for your very large program that uses
the '-r' 'prelinks' of thousands of .o files into handfuls of .o files.
Each 'prelink' merges some hundreds of .o files into a single .o target
file and this work is not repeated in the 'final link' of the few .o files.

Then, a change to a single source file would require a recompile of file.c,
a -r link of file.o into merge1.o and a final link of the few merge*.o files.
In this way, only the hundred or so files which make up merge1.o are again
prelinked, and the other multiple thousands of files are already prelinked,
potentially saving the linker a lot of work.

This method was found, on older releases of HP-UX for huge executable files,
to save significant amounts of link time.  This method could probably save
some link time on just about any vendors' UN*X platform.

Of course, your mileage may vary.  Try it out and see for yourself.
And let us know your results too.

> Bo

Brad Ahlf
bla@hpda.hp.com
This response does not represent the official position of, or statement by,
the Hewlett-Packard Company.  The above data is provided for informational
purposes only.  It is supplied without warranty of any kind.