|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 4817 (0x12d1)
Types: TextFile
Names: »collect2.c«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
└─⟦6f889378a⟧ »./g++-1.36.1.tar.Z«
└─⟦3aa9a3deb⟧
└─⟦this⟧ »g++-1.36.1/collect2.c«
/* Build tables of static constructors and destructors and run ld. */
#include <stdio.h>
#ifdef convex
#define TEXT_SECTION_ASM_OP ".text"
#define DATA_SECTION_ASM_OP ".data"
#define ASM_GLOBALIZE_LABEL(FILE, LABEL) \
fprintf (FILE, ".globl _%s\n", LABEL)
#define ASM_OUTPUT_LABEL(FILE, LABEL) \
fprintf (FILE, "_%s:", LABEL)
#define ASM_OUTPUT_LABELREF(FILE, LABEL) \
fprintf (FILE, "\tds.w _%s\n", LABEL)
#define ASM_OUTPUT_INT(FILE, INT) \
fprintf (FILE, "\tds.w %d\n", INT)
#endif
#if defined (__GNUC__) || defined (sparc)
#define alloca __builtin_alloca
#endif
extern char *mktemp (char *template);
/* Linked lists of constructor and destructor names. */
struct id
{
char *name;
struct id *next;
};
/* Main program. */
main (int argc, char *argv[])
{
static char codexxx[] = "/tmp/codeXXXXXX";
static char asxxx[] = "/tmp/asXXXXXX";
char *codefile, *hookfile, hooksfile[40], hookofile[40];
char *outfile = "a.out";
char *arg, ldargs[1024], cmd[1024];
FILE *inf, *outf;
/* Make temp file names. */
codefile = mktemp (codexxx);
hookfile = mktemp (asxxx);
sprintf (hooksfile, "%s.s", hookfile);
sprintf (hookofile, "%s.o", hookfile);
/* Parse arguments. Remove output file spec, pass the rest to ld. */
ldargs[0] = '\0';
while (arg = *++argv)
{
if (! strcmp (arg, "-o"))
outfile = *++argv;
else
{
strcat (ldargs, " ");
strcat (ldargs, arg);
}
}
/* Load the program, searching all libraries.
Use -r to save the output as a relocatable file.
Examine the namelist with nm and search it for static constructors
and destructors to call.
Write the constructor and destructor tables to a .s file. */
sprintf (cmd, "ld -r -o %s %s && nm -p %s", codefile, ldargs, codefile);
if (! (inf = popen (cmd, "r")))
fatal_perror ("Can't open pipe to ld");
if (! (outf = fopen (hooksfile, "w")))
fatal_perror ("Can't write %s", hooksfile);
write_hooks (inf, outf);
if (pclose (inf) || fclose (outf))
fatal ("load failed");
/* Assemble the constructor and destructor tables.
Link the tables in with the rest of the program. */
sprintf (cmd, "as -o %s %s && ld -o %s %s %s && rm %s %s %s",
hookofile, hooksfile,
outfile, codefile, hookofile,
codefile, hooksfile, hookofile);
exit (system (cmd));
}
/* Scan the name list of the loaded program for the symbols g++ uses
for static constructors and destructors. Write their addresses
into tables which __main and exit will call.
The constructor table __CTOR_LIST__ is an integer count followed by
that many pointers to constructor functions. The destructor table
__DTOR_LIST__ is the same thing, followed by a zero word. */
write_hooks (FILE *inf, FILE *outf)
{
char *p, buf[1024];
struct id *newid;
struct id *constructors = 0;
struct id *destructors = 0;
while (! feof (inf)) {
/* Read a line of nm output and strip the trailing newline. */
fgets (buf, sizeof buf, inf);
p = buf + strlen (buf) - 1;
if (*p == '\n')
*p = '\0';
/* If it contains a constructor or destructor name, add the name
to the appropriate list. */
for (p = buf; *p; p++)
{
while (*p && *p != '_')
p++;
if (! strncmp (p, "_GLOBAL_$I$", 11))
{
newid = alloca (sizeof *newid);
newid->name = alloca (strlen (p) + 1);
strcpy (newid->name, p);
newid->next = constructors;
constructors = newid;
break;
}
else if (! strncmp (p, "_GLOBAL_$D$", 11))
{
newid = alloca (sizeof *newid);
newid->name = alloca (strlen (p) + 1);
strcpy (newid->name, p);
newid->next = destructors;
destructors = newid;
break;
}
}
}
/* Write the tables. */
fprintf (outf, "%s\n", TEXT_SECTION_ASM_OP);
ASM_GLOBALIZE_LABEL (outf, "__CTOR_LIST__");
ASM_OUTPUT_LABEL (outf, "__CTOR_LIST__");
ASM_OUTPUT_INT (outf, count_list (constructors));
write_list (outf, constructors);
fprintf (outf, "%s\n", DATA_SECTION_ASM_OP);
ASM_GLOBALIZE_LABEL (outf, "__DTOR_LIST__");
ASM_OUTPUT_LABEL (outf, "__DTOR_LIST__");
ASM_OUTPUT_INT (outf, count_list (destructors));
write_list (outf, destructors);
ASM_OUTPUT_INT (outf, 0);
}
/* Length of list LIST. */
count_list (struct id *list)
{
int count = 0;
while (list)
{
count++;
list = list->next;
}
return count;
}
/* Write the names on list LIST, in reverse order. */
write_list (FILE *outf, struct id *list)
{
if (! list)
return;
write_list (outf, list->next);
ASM_OUTPUT_LABELREF (outf, list->name);
}
/* Die when sys call fails. */
fatal_perror (string, arg)
{
char buf[80];
sprintf (buf, string, arg);
perror (buf);
exit (1);
}
/* Just die. */
fatal (string)
{
fprintf (stderr, string);
exit (1);
}