Path: utzoo!attcan!uunet!know!sdd.hp.com!hp-pcd!hpfcso!mjs From: mjs@hpfcso.HP.COM (Marc Sabatella) Newsgroups: comp.sys.hp Subject: Re: HP-UX `ld' tricks. Message-ID: <7370247@hpfcso.HP.COM> Date: 5 Nov 90 18:32:16 GMT References: <1783@kuling.UUCP> Organization: Hewlett-Packard, Fort Collins, CO, USA Lines: 82 >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 " 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 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 #include /* 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 " 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