1329 lines
27 KiB
C
1329 lines
27 KiB
C
#ifndef lint
|
|
static char sccsid[] = "@(#)setup.c 1.1 94/10/31 SMI";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1987 by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
#include "driver.h"
|
|
|
|
/* assy_source_is_from_compiler==TRUE if ass'y code has just
|
|
* been generated by the compiler (which is the default
|
|
* case).
|
|
*/
|
|
static Bool assy_source_is_from_compiler = TRUE;
|
|
|
|
/*
|
|
* clear_program_options:
|
|
* Clear all dynamic fields for all programs (get ready for new ones).
|
|
*/
|
|
void
|
|
clear_program_options()
|
|
{
|
|
register ProgramP p;
|
|
|
|
for (p= (ProgramP)&program; p->name != NULL; p++)
|
|
p->options= p->infile= NULL;
|
|
} /* clear_program_options */
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* The compile functions that are referenced from the "compile" field for
|
|
* the suffixes. Each function is responsible for compiling one file with
|
|
* the specified suffix.
|
|
*
|
|
* The function either calls run_steps() directly or it sets some state
|
|
* calls a lower compile_*() function to do the work.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
/*
|
|
* compile_s
|
|
*/
|
|
int
|
|
compile_s(source)
|
|
char *source;
|
|
{
|
|
int status;
|
|
|
|
clear_program_options();
|
|
assy_source_is_from_compiler = FALSE;
|
|
status= run_steps(source, s_steps, FALSE, "");
|
|
assy_source_is_from_compiler = TRUE;
|
|
return status;
|
|
} /* compile_s */
|
|
|
|
/*
|
|
* compile_S
|
|
* -- same as compile_s(), except for ass'y source w/.S suffix
|
|
*/
|
|
int
|
|
compile_S(source)
|
|
char *source;
|
|
{
|
|
int status;
|
|
|
|
set_flag(do_cpp);
|
|
status= compile_s(source);
|
|
reset_flag(do_cpp);
|
|
return status;
|
|
} /* compile_S */
|
|
|
|
/*
|
|
* setup_tcov_file
|
|
*/
|
|
void
|
|
setup_tcov_file(source)
|
|
char *source;
|
|
{
|
|
char *q;
|
|
char buffer[MAXPATHLEN+1+4]; /* "+4" is for "-A" & ".d" */
|
|
static char *pwd= NULL;
|
|
|
|
(void)strcpy(buffer, "-A");
|
|
if (source[0] != '/'){
|
|
if (pwd == NULL)
|
|
{
|
|
char pwd_buffer[MAXPATHLEN+1];
|
|
|
|
/* getwd() is expensive, so we only do it *once*. */
|
|
if ( is_on(testing_driver) )
|
|
{
|
|
strcpy(pwd_buffer, "/PWD");
|
|
}
|
|
else
|
|
{
|
|
(void)getwd(pwd_buffer);
|
|
}
|
|
pwd= make_string(pwd_buffer);
|
|
}
|
|
(void)strcat(buffer, pwd);
|
|
(void)strcat(buffer, "/");
|
|
}
|
|
(void)strcat(buffer, source);
|
|
if ((q= rindex(buffer, '.')) == NULL)
|
|
(void)strcat(buffer, ".d");
|
|
else
|
|
{
|
|
*(q+1)= 'd';
|
|
*(q+2)= '\0';
|
|
}
|
|
tcov_file= make_string(buffer);
|
|
} /* setup_tcov_file */
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* The collect functions that are referenced from the "collect" field for
|
|
* the suffixes. Each function is resonsible for collecting one file for
|
|
* later postprocessing.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
/*
|
|
* collect_o
|
|
*/
|
|
void collect_o(file, suffix)
|
|
char *file;
|
|
SuffixP suffix;
|
|
{
|
|
if (is_off(doing_mod_file))
|
|
append_list_with_suffix(&infile_o, file, suffix);
|
|
} /* collect_o */
|
|
|
|
/*
|
|
* collect_ln
|
|
*/
|
|
void collect_ln(file, suffix)
|
|
char *file;
|
|
SuffixP suffix;
|
|
{
|
|
append_list_with_suffix(&infile_ln, file, suffix);
|
|
} /* collect_ln */
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* The setup functions that are referenced from the "setup" field of the
|
|
* program description. They are responsible for establishing the
|
|
* environment the program needs to run. Specifically they return the
|
|
* name of the outfile they want written. It they return NULL run_pass()
|
|
* will provide a name.
|
|
*
|
|
* Each function starts with a section that sets the permanent options for
|
|
* the program. This only runs once.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
/*
|
|
* setup_cpp
|
|
*/
|
|
/*ARGSUSED*/
|
|
char *
|
|
setup_cpp(original_source, source)
|
|
char *original_source;
|
|
char *source;
|
|
{
|
|
char buffer[LOCAL_STRING_LENGTH];
|
|
|
|
if (!program.cpp.has_been_initialized)
|
|
{
|
|
program.cpp.has_been_initialized = TRUE;
|
|
#ifndef sun386
|
|
append_list(&program.cpp.permanent_options, "-undef");
|
|
#endif /*!sun386*/
|
|
if (driver.value == &xlint)
|
|
{
|
|
append_list(&program.cpp.permanent_options, "-C");
|
|
append_list(&program.cpp.permanent_options, "-Dlint");
|
|
}
|
|
|
|
/* Depending on which target we run for, we define different
|
|
* -D options.
|
|
*/
|
|
|
|
/* All Sun target architectures get -Dunix and -Dsun. */
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN2:
|
|
case ARCH_SUN3X:
|
|
case ARCH_SUN386:
|
|
case ARCH_SUN3:
|
|
case ARCH_SUN4C:
|
|
case ARCH_SUN4:
|
|
append_list(&program.cpp.permanent_options, "-Dunix");
|
|
append_list(&program.cpp.permanent_options, "-Dsun");
|
|
break;
|
|
case ARCH_FOREIGN:
|
|
/* foreign architecture: let them set their own. */
|
|
break;
|
|
default:
|
|
/* nothing to do. */
|
|
break;
|
|
}
|
|
|
|
/* All Sun target architectures get the target processor
|
|
* predefined. In addition, the Motorola-based ones also get
|
|
* the generic "mc68000" defined.
|
|
*/
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN2:
|
|
case ARCH_SUN3X:
|
|
case ARCH_SUN3:
|
|
append_list(&program.cpp.permanent_options,"-Dmc68000");
|
|
/* fall through */
|
|
case ARCH_SUN386:
|
|
case ARCH_SUN4C:
|
|
case ARCH_SUN4:
|
|
strcpy(buffer, "-D");
|
|
strcat(buffer, get_processor_type(target_arch.value));
|
|
append_list(&program.cpp.permanent_options,
|
|
make_string(buffer));
|
|
break;
|
|
case ARCH_FOREIGN:
|
|
/* foreign architecture: let them set their own. */
|
|
break;
|
|
default:
|
|
/* nothing to do. */
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef BROWSER
|
|
if (is_on(code_browser) &&
|
|
(product.value != &preprocessed) &&
|
|
(product.value != &preprocessed2)) {
|
|
append_list(&program.cpp.options, "-cb");
|
|
}
|
|
#endif
|
|
if (is_on(do_dependency))
|
|
{
|
|
append_list(&program.cpp.options, "-M");
|
|
}
|
|
|
|
switch (target_sw_release[R_PATHS].value->value)
|
|
{
|
|
case SW_REL_3X:
|
|
case SW_REL_40:
|
|
if (is_on(sys5_flag))
|
|
{
|
|
/* system 5 and release 3.x or 4.0 */
|
|
append_list(&program.cpp.infile, "-I/usr/5include");
|
|
}
|
|
break;
|
|
case SW_REL_41:
|
|
if (is_on(sys5_flag))
|
|
{
|
|
/* sys5 and release 4.1 */
|
|
append_list(&program.cpp.infile, "-I/usr/5include");
|
|
}
|
|
break;
|
|
default:
|
|
fatal("Invalid target sw release");
|
|
break;
|
|
}
|
|
|
|
if (product.value == &preprocessed)
|
|
{
|
|
if (outfile == NULL)
|
|
{
|
|
append_list(&program.cpp.infile, source);
|
|
return "";
|
|
}
|
|
}
|
|
return NULL;
|
|
} /* setup_cpp */
|
|
|
|
/*
|
|
* Copy all "-Qoption f1" options from the f1 option list to mf1
|
|
*/
|
|
void
|
|
f1_to_mf1_copy()
|
|
{
|
|
ListP p;
|
|
static int already_done= 0;
|
|
|
|
if (!already_done)
|
|
{
|
|
already_done= 1;
|
|
for (p= program.f1.permanent_options; p != NULL; p= p->next)
|
|
append_list(&program.mf1.permanent_options, p->value);
|
|
for (p= program.f1.trailing_options; p != NULL; p= p->next)
|
|
append_list(&program.mf1.trailing_options, p->value);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* setup_inline()
|
|
*/
|
|
char *
|
|
setup_inline()
|
|
{
|
|
if ( is_on(handle_misalignment) )
|
|
{
|
|
append_list(&program.inline.options, "-i");
|
|
append_list(&program.inline.options,
|
|
scan_Qpath_and_vroot("/usr/lib/misalign.il", TRUE));
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* setup_iropt
|
|
*/
|
|
static char *
|
|
setup_iropt(iropt_program)
|
|
Program *iropt_program;
|
|
{
|
|
char buffer[LOCAL_STRING_LENGTH];
|
|
register char *p;
|
|
|
|
if (!iropt_program->has_been_initialized)
|
|
{
|
|
iropt_program->has_been_initialized = TRUE;
|
|
(void)sprintf(buffer, "-O%c", optimizer_level);
|
|
append_list(&(iropt_program->permanent_options),
|
|
make_string(buffer));
|
|
|
|
if (is_on(pic_code) || is_on(PIC_code))
|
|
append_list(&(iropt_program->permanent_options), "-k");
|
|
|
|
/* Build compound option argument */
|
|
p= buffer;
|
|
*p++= '-';
|
|
|
|
switch (float_mode.value->value)
|
|
{
|
|
case FLOAT_FPA:
|
|
*p++= 'f';
|
|
break;
|
|
case FLOAT_SKY:
|
|
*p++= 'F';
|
|
break;
|
|
case FLOAT_68881:
|
|
if ( is_off(fstore) )
|
|
{
|
|
*p++= 'm';
|
|
}
|
|
break;
|
|
}
|
|
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN3X:
|
|
case ARCH_SUN3:
|
|
*p++= 'c';
|
|
break;
|
|
case ARCH_SUN386:
|
|
if (is_on(fstore))
|
|
{
|
|
*p++= 'm';
|
|
}
|
|
*p++= 'c';
|
|
break;
|
|
default:
|
|
/* do nothing */
|
|
break;
|
|
}
|
|
|
|
*p= '\0';
|
|
|
|
if (strlen(buffer) > 1)
|
|
{
|
|
/* More than "-" was left in buffer. */
|
|
append_list(&(iropt_program->permanent_options),
|
|
make_string(buffer));
|
|
}
|
|
}
|
|
return NULL;
|
|
} /* setup_iropt */
|
|
|
|
/*
|
|
* setup_iropt_all()
|
|
*/
|
|
char *
|
|
setup_iropt_all()
|
|
{
|
|
return setup_iropt( &(program.iropt) );
|
|
}
|
|
|
|
/*
|
|
* setup_iropt_f77()
|
|
*/
|
|
char *
|
|
setup_iropt_f77()
|
|
{
|
|
if (target_sw_release[R_PASSES].value->value >= SW_REL_40)
|
|
{
|
|
program.iropt.path = "/usr/lib/f77/iropt";
|
|
}
|
|
return setup_iropt( &(program.iropt) );
|
|
}
|
|
|
|
|
|
/*
|
|
* setup_iropt_mod()
|
|
*/
|
|
char *
|
|
setup_iropt_mod()
|
|
{
|
|
|
|
if (target_sw_release[R_PASSES].value->value >= SW_REL_40)
|
|
{
|
|
program.iropt.path = "/usr/lib/modula2/iropt";
|
|
}
|
|
return setup_iropt( &(program.iropt) );
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
* setup_iropt_pc()
|
|
*/
|
|
char *
|
|
setup_iropt_pc()
|
|
{
|
|
if (target_sw_release[R_PASSES].value->value >= SW_REL_40)
|
|
{
|
|
program.iropt.path = "/usr/lib/pascal/iropt";
|
|
}
|
|
return setup_iropt( &(program.iropt) );
|
|
}
|
|
|
|
|
|
/*
|
|
* setup_cg()
|
|
*/
|
|
static char *
|
|
setup_cg(cg_program)
|
|
Program *cg_program;
|
|
{
|
|
if (!cg_program->has_been_initialized)
|
|
{
|
|
cg_program->has_been_initialized = TRUE;
|
|
if (profile.touched)
|
|
append_list(&cg_program->permanent_options, "-p");
|
|
if (is_on(pic_code))
|
|
append_list(&cg_program->permanent_options, "-k");
|
|
if (is_on(PIC_code))
|
|
append_list(&cg_program->permanent_options, "-K");
|
|
if (is_on(generate_nonzero_activation_records))
|
|
append_list(&cg_program->permanent_options, "-bnzero");
|
|
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN2:
|
|
case ARCH_SUN3X:
|
|
case ARCH_SUN3:
|
|
if (is_on(long_offset))
|
|
{
|
|
append_list(&cg_program->permanent_options,
|
|
"-J");
|
|
}
|
|
append_list(&cg_program->permanent_options,
|
|
float_mode.value->name);
|
|
append_list(&cg_program->permanent_options,
|
|
get_processor_flag(target_arch.value));
|
|
break;
|
|
case ARCH_SUN4C:
|
|
case ARCH_SUN4:
|
|
if ( is_on(handle_misalignment) )
|
|
{
|
|
append_list(&cg_program->permanent_options,
|
|
"-m");
|
|
}
|
|
|
|
|
|
if ( ( target_sw_release[R_PASSES].value->value
|
|
>= SW_REL_41 )
|
|
||
|
|
/* or if this is release 4.0 and vers 1.2 of f77 */
|
|
(check_release_version_driver(SW_REL_40,DRIVER_REL_12,DRIVER_F) ) )
|
|
|
|
{
|
|
if ( is_on(doubleword_aligned_doubles) )
|
|
{
|
|
append_list(&cg_program->permanent_options,
|
|
"-d");
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
/* do nothing. */
|
|
break;
|
|
}
|
|
}
|
|
return NULL;
|
|
} /* setup_cg */
|
|
|
|
/*
|
|
* setup_cg_all()
|
|
*/
|
|
char *
|
|
setup_cg_all()
|
|
{
|
|
return setup_cg( &(program.cg) );
|
|
}
|
|
|
|
/*
|
|
* setup_cg_f77()
|
|
*/
|
|
char *
|
|
setup_cg_f77()
|
|
{
|
|
if (target_sw_release[R_PASSES].value->value >= SW_REL_40)
|
|
{
|
|
program.cg.path = "/usr/lib/f77/cg";
|
|
}
|
|
|
|
/* we need to also check for tcov flag
|
|
* setup appropriately
|
|
*/
|
|
setup_cg_f77_for_tcov();
|
|
/* setup_cg_for_tcov( &(program.cg) ); */
|
|
|
|
return setup_cg( &(program.cg) );
|
|
}
|
|
|
|
|
|
/*
|
|
* setup_cg_mod()
|
|
*/
|
|
char *
|
|
setup_cg_mod()
|
|
{
|
|
|
|
if (target_sw_release[R_PASSES].value->value >= SW_REL_40)
|
|
{
|
|
program.cg.path = "/usr/lib/modula2/cg";
|
|
}
|
|
return setup_cg( &(program.cg) );
|
|
}
|
|
|
|
|
|
/*
|
|
* setup_cg_pc()
|
|
*/
|
|
char *
|
|
setup_cg_pc()
|
|
{
|
|
|
|
if (target_sw_release[R_PASSES].value->value >= SW_REL_40)
|
|
{
|
|
program.cg.path = "/usr/lib/pascal/cg";
|
|
}
|
|
return setup_cg( &(program.cg) );
|
|
}
|
|
|
|
|
|
/*
|
|
* setup_c2
|
|
*/
|
|
char *
|
|
setup_c2()
|
|
{
|
|
|
|
if (!program.c2.has_been_initialized)
|
|
{
|
|
program.c2.has_been_initialized = TRUE;
|
|
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN2:
|
|
append_list(&program.c2.permanent_options, "-10");
|
|
break;
|
|
case ARCH_SUN3X:
|
|
/* Believe it or not, there is no "-30" flag to c2;
|
|
* we just pass it "-20" for the sun3x target.
|
|
* -- fall thru --
|
|
*/
|
|
case ARCH_SUN3:
|
|
append_list(&program.c2.permanent_options, "-20");
|
|
break;
|
|
default:
|
|
/* do nothing. */
|
|
break;
|
|
}
|
|
|
|
if (optimizer_level > OPTIM_NONE)
|
|
{
|
|
/* if this is release 4.1 */
|
|
if ( ( target_sw_release[R_PASSES].value->value
|
|
>= SW_REL_41 )
|
|
|
|
||
|
|
|
|
/* or this is sun3x and release 4.0 */
|
|
( ( target_sw_release[R_PASSES].value->value == SW_REL_40 )
|
|
&&
|
|
(target_arch.value->value == ARCH_SUN3X) )
|
|
||
|
|
/* or if this is release 4.0 and vers 1.2 of f77 */
|
|
(check_release_version_driver(SW_REL_40,DRIVER_REL_12,DRIVER_F) ) )
|
|
{
|
|
/* new flags for 4.1 c2 */
|
|
switch ( float_mode.value->value )
|
|
{
|
|
case FLOAT_FPA:
|
|
append_list(&program.c2.permanent_options,
|
|
"-dfpascheduling");
|
|
break;
|
|
case FLOAT_68881:
|
|
append_list(&program.c2.permanent_options,
|
|
"-d881scheduling");
|
|
default:
|
|
/* do nothing */
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( float_mode.value->value )
|
|
{
|
|
case FLOAT_FPA:
|
|
append_list(&program.c2.permanent_options,
|
|
"-dscheduling");
|
|
break;
|
|
default:
|
|
/* nothing to do. */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_on(pic_code) || is_on(PIC_code))
|
|
{
|
|
append_list(&program.c2.permanent_options, "-k");
|
|
}
|
|
}
|
|
return NULL;
|
|
} /* setup_c2 */
|
|
|
|
/*
|
|
* Copy all "-Qoption as" options from the as option list to asS
|
|
*/
|
|
void
|
|
as_to_asS_copy()
|
|
{
|
|
ListP p;
|
|
static int already_done= 0;
|
|
|
|
if (!already_done)
|
|
{
|
|
already_done= 1;
|
|
for (p= program.as.permanent_options; p != NULL; p= p->next)
|
|
append_list(&program.asS.permanent_options, p->value);
|
|
for (p= program.as.trailing_options; p != NULL; p= p->next)
|
|
append_list(&program.asS.trailing_options, p->value);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* setup_as
|
|
*/
|
|
char *
|
|
setup_as()
|
|
{
|
|
char buffer[LOCAL_STRING_LENGTH];
|
|
|
|
if (!program.as.has_been_initialized)
|
|
{
|
|
|
|
program.as.has_been_initialized = TRUE;
|
|
as_to_asS_copy();
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN2:
|
|
case ARCH_SUN3X:
|
|
case ARCH_SUN3:
|
|
if ( (optimizer_level > OPTIM_IROPT_P) &&
|
|
(assy_source_is_from_compiler) )
|
|
{
|
|
append_list(&program.as.permanent_options,
|
|
"-O");
|
|
}
|
|
append_list(&program.as.permanent_options,
|
|
get_processor_flag(target_arch.value));
|
|
break;
|
|
default:
|
|
/* do nothing. */
|
|
break;
|
|
}
|
|
if (is_on(pic_code) || is_on(PIC_code))
|
|
{
|
|
append_list(&program.as.permanent_options, "-k");
|
|
}
|
|
if (is_on(as_R))
|
|
{
|
|
append_list(&program.as.permanent_options, "-R");
|
|
}
|
|
}
|
|
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN4C:
|
|
case ARCH_SUN4:
|
|
if ( (optimizer_level > OPTIM_NONE) && is_off(no_c2) &&
|
|
(assy_source_is_from_compiler) )
|
|
{
|
|
(void)sprintf(buffer, "-O%c", optimizer_level);
|
|
append_list(&program.as.options, make_string(buffer));
|
|
}
|
|
if ( assy_source_is_from_compiler &&
|
|
(optimizer_level == OPTIM_NONE) )
|
|
{
|
|
append_list(&program.as.options, "-Q");
|
|
}
|
|
break;
|
|
default:
|
|
/* do nothing. */
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
|
|
} /* setup_as */
|
|
|
|
/*
|
|
* setup_asS
|
|
* -- same as setup_as(), except for SPARC assembler when -S is used.
|
|
*/
|
|
void
|
|
setup_asS()
|
|
{
|
|
char buffer[LOCAL_STRING_LENGTH];
|
|
|
|
if (!program.asS.has_been_initialized)
|
|
{
|
|
program.asS.has_been_initialized = TRUE;
|
|
as_to_asS_copy();
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN4C:
|
|
case ARCH_SUN4:
|
|
append_list(&program.asS.permanent_options, "-S");
|
|
if (product.value == &assembler)
|
|
{
|
|
append_list(&program.asS.permanent_options,
|
|
"-o");
|
|
append_list(&program.asS.permanent_options,
|
|
"/dev/null");
|
|
}
|
|
break;
|
|
default:
|
|
fatal("Internal Error: setup_asS(): target=%d?",
|
|
target_arch.value->value);
|
|
}
|
|
if (is_on(pic_code) || is_on(PIC_code))
|
|
{
|
|
append_list(&program.asS.permanent_options, "-k");
|
|
}
|
|
if (is_on(as_R))
|
|
{
|
|
append_list(&program.asS.permanent_options, "-R");
|
|
}
|
|
}
|
|
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN4C:
|
|
case ARCH_SUN4:
|
|
if ( (optimizer_level > OPTIM_NONE) && is_off(no_c2) &&
|
|
(assy_source_is_from_compiler) )
|
|
{
|
|
(void)sprintf(buffer, "-O%c", optimizer_level);
|
|
append_list(&program.asS.options, make_string(buffer));
|
|
}
|
|
if ( assy_source_is_from_compiler &&
|
|
(optimizer_level == OPTIM_NONE) )
|
|
{
|
|
append_list(&program.asS.options, "-Q");
|
|
}
|
|
break;
|
|
default:
|
|
/* do nothing. */
|
|
break;
|
|
}
|
|
|
|
} /* setup_asS */
|
|
|
|
|
|
/*
|
|
* get_crt0_name()
|
|
* Returns the name of the appropriate crt0 file.
|
|
*/
|
|
char *
|
|
get_crt0_name()
|
|
{
|
|
if ( is_on(handle_misalignment) )
|
|
{
|
|
/* To handle misalignment, we must get the crt0 file from a
|
|
* different directory.
|
|
*/
|
|
char buffer[100];
|
|
char *misalign_dir;
|
|
|
|
switch (target_sw_release[R_PATHS].value->value)
|
|
{
|
|
case SW_REL_40:
|
|
if (is_on(sys5_flag))
|
|
{
|
|
/* system 5 and release 4.0 */
|
|
misalign_dir = "/usr/5lib";
|
|
}
|
|
else
|
|
{
|
|
/* bsd and release 4.0 */
|
|
misalign_dir = "/usr/lib";
|
|
}
|
|
break;
|
|
case SW_REL_41:
|
|
/* 7/13/88 according to aoki there is
|
|
* only one location for misalign
|
|
*/
|
|
{
|
|
misalign_dir ="/usr/lib";
|
|
}
|
|
break;
|
|
|
|
default:
|
|
fatal("Invalid sw release for misalignment");
|
|
break;
|
|
}
|
|
|
|
sprintf(buffer, "%s/misalign%s", misalign_dir,
|
|
rindex(profile.value->extra, '/') );
|
|
|
|
return make_string(buffer);
|
|
}
|
|
else
|
|
{
|
|
/* Just use the regular crt0. */
|
|
return profile.value->extra;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* setup_link_step
|
|
*/
|
|
char *
|
|
setup_link_step()
|
|
{
|
|
switch (driver.value->value)
|
|
{
|
|
case DRIVER_C:
|
|
return setup_ld_for_cc();
|
|
case DRIVER_F:
|
|
return setup_ld_for_f77();
|
|
case DRIVER_M:
|
|
return setup_m2l_for_m2c();
|
|
case DRIVER_P:
|
|
return setup_ld_for_pc();
|
|
}
|
|
return "";
|
|
} /* setup_link_step */
|
|
|
|
/*
|
|
* setup_ld()
|
|
* Generic setup for linker, called by setup_ld_for_*() functions.
|
|
*/
|
|
char *
|
|
setup_ld(minus_u_options, libraries, profiled_libraries)
|
|
char *(minus_u_options[]);
|
|
char *(libraries[]);
|
|
char *(profiled_libraries[]);
|
|
{
|
|
register ListP p;
|
|
register int i;
|
|
char buffer[LOCAL_STRING_LENGTH];
|
|
#ifdef PASCAL_105
|
|
extern Bool special_pascal_105_case;
|
|
#endif /*PASCAL_105*/
|
|
|
|
if (!program.ld.has_been_initialized)
|
|
{
|
|
program.ld.has_been_initialized = TRUE;
|
|
if (target_sw_release[R_PASSES].value->value >= SW_REL_40)
|
|
{
|
|
/* new flags for 4.x ld */
|
|
#ifdef PASCAL_105
|
|
/* Special-case for Pascal 1.05 for Sun-4 target:
|
|
* treat it as if the compiler passes were 4.0 passes,
|
|
* except must use regular 3.x linker pass/flags.
|
|
*/
|
|
if ( !special_pascal_105_case )
|
|
#endif /*PASCAL_105*/
|
|
{
|
|
/* do not append for sun386 arch */
|
|
if (target_arch.value->value == ARCH_SUN386)
|
|
{
|
|
if (driver.value->value == DRIVER_C)
|
|
{
|
|
append_list(&program.ld.permanent_options, "-dc");
|
|
append_list(&program.ld.permanent_options, "-dp");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
append_list(&program.ld.permanent_options, "-dc");
|
|
append_list(&program.ld.permanent_options, "-dp");
|
|
}
|
|
}
|
|
}
|
|
append_list(&program.ld.permanent_options, "-e");
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN386:
|
|
append_list(&program.ld.permanent_options, "_start");
|
|
break;
|
|
default:
|
|
append_list(&program.ld.permanent_options, "start");
|
|
break;
|
|
}
|
|
|
|
if (minus_u_options != NULL)
|
|
{
|
|
for (i = 0; minus_u_options[i] != NULL; i++)
|
|
{
|
|
append_list(&program.ld.permanent_options,
|
|
minus_u_options[i]);
|
|
}
|
|
}
|
|
append_list(&program.ld.permanent_options, "-X");
|
|
}
|
|
|
|
if (is_on(vpa))
|
|
{
|
|
/* ld output is a temporary file to be passed to vpald. */
|
|
program.ld.outfile= temp_file_name(&program.ld,
|
|
&suffix.none, 0);
|
|
ld_to_vpa_file = program.ld.outfile;
|
|
}
|
|
else
|
|
{
|
|
/* ld is the last step. */
|
|
program.ld.outfile= (outfile == NULL) ? "a.out" : outfile;
|
|
for (p= infile; p != NULL; p= p->next)
|
|
if (STR_EQUAL(program.ld.outfile, p->value))
|
|
fatal("Outfile %s would overwrite infile",
|
|
p->value);
|
|
}
|
|
|
|
/* Add crt0.o file */
|
|
append_list(&program.ld.infile,
|
|
scan_Qpath_and_vroot(get_crt0_name(), TRUE));
|
|
|
|
/* Add crt1.o routine */
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN2:
|
|
case ARCH_SUN3X:
|
|
case ARCH_SUN3:
|
|
if (float_mode.value->extra != NULL)
|
|
{
|
|
append_list(&program.ld.infile,
|
|
scan_Qpath_and_vroot(float_mode.value->extra,
|
|
TRUE));
|
|
}
|
|
break;
|
|
default:
|
|
/* Don't need special floating-point runtime code */
|
|
break;
|
|
}
|
|
|
|
/* Add bb_link.o routine, if -a is enabled */
|
|
if (is_on(statement_count))
|
|
{
|
|
append_list(&program.ld.infile,
|
|
scan_Qpath_and_vroot("/usr/lib/bb_link.o", TRUE));
|
|
}
|
|
|
|
if ( is_on(handle_misalignment) )
|
|
{
|
|
switch (target_sw_release[R_PATHS].value->value)
|
|
{
|
|
case SW_REL_40:
|
|
if (is_on(sys5_flag))
|
|
{
|
|
/* system 5 and release 4.0 */
|
|
append_list(&program.ld.infile, "-L/usr/5lib/misalign");
|
|
}
|
|
else
|
|
{
|
|
/* ucb and release 4.0 */
|
|
append_list(&program.ld.infile, "-L/usr/lib/misalign");
|
|
}
|
|
break;
|
|
case SW_REL_41:
|
|
/* 7/13/88 according to aoki there is
|
|
* only one location for misalign
|
|
*/
|
|
{
|
|
append_list(&program.ld.infile, "-L/usr/lib/misalign");
|
|
}
|
|
break;
|
|
default:
|
|
fatal("Invalid sw release for misalignment");
|
|
}
|
|
|
|
}
|
|
|
|
switch (target_arch.value->value)
|
|
{
|
|
case ARCH_SUN2:
|
|
case ARCH_SUN3X:
|
|
case ARCH_SUN3:
|
|
if (target_sw_release[R_PATHS].value->value != SW_REL_3X)
|
|
{
|
|
/* Add /usr/lib/f... search path for libraries. */
|
|
(void)sprintf(buffer, "-L/usr/lib/%s",
|
|
float_mode.value->name+1);
|
|
append_list(&program.ld.infile, make_string(buffer));
|
|
}
|
|
break;
|
|
case ARCH_SUN386:
|
|
case ARCH_SUN4C:
|
|
case ARCH_SUN4:
|
|
case ARCH_FOREIGN:
|
|
break;
|
|
default:
|
|
fatal("Invalid target architecture (%d)",
|
|
target_arch.value->value);
|
|
}
|
|
|
|
for (p= infile_o; p != NULL; p= p->next)
|
|
{
|
|
append_list(&program.ld.infile, p->value);
|
|
}
|
|
|
|
if (debugger.touched)
|
|
{
|
|
/* Add the debugger library to the command line. */
|
|
append_list(&program.ld.infile, "-lg");
|
|
}
|
|
|
|
if (profile.touched)
|
|
{
|
|
if (is_on(vpa))
|
|
{
|
|
/* Add the vpa library to the command line. */
|
|
append_list(&program.ld.infile, "-lvpa_p");
|
|
}
|
|
if (profiled_libraries != NULL)
|
|
{
|
|
/* Add the standard libraries to the command line. */
|
|
for (i = 0; profiled_libraries[i] != NULL; i++)
|
|
{
|
|
append_list(&program.ld.infile,
|
|
profiled_libraries[i]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (is_on(vpa))
|
|
{
|
|
/* Add the vpa library to the command line. */
|
|
append_list(&program.ld.infile, "-lvpa");
|
|
}
|
|
if (libraries != NULL)
|
|
{
|
|
/* Add the standard libraries to the command line. */
|
|
for (i = 0; libraries[i] != NULL; i++)
|
|
{
|
|
append_list(&program.ld.infile, libraries[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (target_sw_release[R_PATHS].value->value)
|
|
{
|
|
case SW_REL_3X:
|
|
case SW_REL_40:
|
|
if (is_on(sys5_flag))
|
|
{
|
|
/* system 5 and release 3.x or 4.0 */
|
|
append_list(&program.ld.infile, "-L/usr/5lib");
|
|
}
|
|
break;
|
|
case SW_REL_41:
|
|
if (is_on(sys5_flag))
|
|
{
|
|
/* sys5 and release 4.1 */
|
|
append_list(&program.ld.infile, "-L/usr/5lib");
|
|
}
|
|
break;
|
|
default:
|
|
fatal("Invalid target sw release");
|
|
/*NOTREACHED*/
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
/*
|
|
* setup_vpald
|
|
*/
|
|
char *
|
|
setup_vpald()
|
|
{
|
|
register ListP p;
|
|
|
|
program.vpald.outfile= (outfile == NULL) ? "a.out" : outfile;
|
|
for (p= infile; p != NULL; p= p->next)
|
|
if (STR_EQUAL(program.vpald.outfile, p->value))
|
|
fatal("Outfile %s would overwrite infile", p->value);
|
|
append_list(&program.vpald.infile, ld_to_vpa_file);
|
|
return "";
|
|
} /* setup_vpald */
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* The setup functions that are referenced from the "setup" field of the
|
|
* step description follow.
|
|
* They are responsible for establishing the environment the program needs
|
|
* to run this step. Specifically they return the name of the outfile
|
|
* they want written. It they return NULL, run_pass() or the program
|
|
* setup() will provide a name.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
/*
|
|
* setup_ccom_for_iropt
|
|
* ccom produces two outfiles when running for iropt;
|
|
* one iropt file (containing IR for the Text segment)
|
|
* and one assembly file (containing the Data segment).
|
|
*/
|
|
char *
|
|
setup_ccom_for_iropt(source, file)
|
|
char *source;
|
|
char *file;
|
|
{
|
|
char buffer[LOCAL_STRING_LENGTH];
|
|
|
|
(void)setup_ccom();
|
|
append_list(&program.ccom.infile, file);
|
|
/* program.ccom.outfile is referenced in setup_as_for_cc(), to get the
|
|
* name of the extra infile.
|
|
*/
|
|
program.ccom.outfile= temp_file_name(&program.ccom, &suffix.s, 0);
|
|
(void)sprintf(buffer, "-XO%c", optimizer_level);
|
|
append_list(&program.ccom.options, make_string(buffer));
|
|
append_list(&program.ccom.options,
|
|
source= temp_file_name(&program.ccom, &suffix.ir, 0));
|
|
return source;
|
|
} /* setup_ccom_for_iropt */
|
|
|
|
|
|
/*
|
|
* setup_cg_for_tcov()
|
|
* When -a option is given, cg needs the -A option built for
|
|
* f77pass1.
|
|
*/
|
|
char *
|
|
setup_cg_for_tcov(cg_program)
|
|
Program *cg_program;
|
|
{
|
|
if (is_on(statement_count))
|
|
append_list(&cg_program->infile, tcov_file);
|
|
return NULL;
|
|
} /* setup_cg_for_tcov */
|
|
|
|
/*
|
|
* setup_cg_cc_for_tcov()
|
|
*/
|
|
char *
|
|
setup_cg_cc_for_tcov()
|
|
{
|
|
return setup_cg_for_tcov( &(program.cg) );
|
|
}
|
|
|
|
/*
|
|
* setup_cg_f77_for_tcov()
|
|
*/
|
|
char *
|
|
setup_cg_f77_for_tcov()
|
|
{
|
|
|
|
return setup_cg_for_tcov( &(program.cg) );
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* do_infiles
|
|
* This is the basic loop that runs thru the list of infiles
|
|
* and processes each one.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
do_infiles()
|
|
{
|
|
register ListP cp;
|
|
register SuffixP save_suffix;
|
|
Named_int save_product;
|
|
|
|
for (cp= infile; cp != NULL; cp= cp->next)
|
|
{
|
|
/* Trace compilations */
|
|
if ((source_infile_count > 1) &&
|
|
is_off(do_dependency) /* not using "-M" */ &&
|
|
((cp->suffix->in_drivers&SOURCE_SUFFIX) == SOURCE_SUFFIX))
|
|
{
|
|
(void)printf("%s:\n", cp->value);
|
|
}
|
|
|
|
reset_flag(doing_mod_file);
|
|
save_suffix= requested_suffix;
|
|
save_product= product;
|
|
|
|
/* If this is a Modula define file we cheat and say we
|
|
* absolutely want a .sym file.
|
|
*/
|
|
if (cp->suffix == &suffix.def)
|
|
{
|
|
requested_suffix= &suffix.sym;
|
|
product.value= NULL;
|
|
}
|
|
if (cp->suffix == &suffix.mod)
|
|
{
|
|
set_flag(doing_mod_file);
|
|
}
|
|
|
|
/* if this is a .ln file, with a bogus DUMMY_FLAG at the
|
|
* beginnning we need to replace the DUMMY_FLAG with a
|
|
* proper path. The reason for this is that the sw_release
|
|
* was unknown at the time the command line was parsed.
|
|
* This will occur only with the -l option for lint
|
|
*/
|
|
if ((cp->suffix == &suffix.ln) && (!strncmp(cp->value,DUMMY_FLAG,DUMMY_LENGTH)))
|
|
{
|
|
strcpy(cp->value,special_lint_l(cp->value));
|
|
}
|
|
|
|
/* Call the compile or collect function */
|
|
if (cp->suffix->compile != NULL)
|
|
{
|
|
exit_status|= (*cp->suffix->compile)(cp->value);
|
|
}
|
|
else
|
|
{
|
|
if (cp->suffix->collect != NULL)
|
|
(*cp->suffix->collect)(cp->value, cp->suffix);
|
|
}
|
|
|
|
requested_suffix= save_suffix;
|
|
product= save_product;
|
|
}
|
|
} /* do_infiles */
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* set_requested_suffix
|
|
* Figure out what the suffix of the file we want to make is.
|
|
* The product Named_int Const_int carries the information.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
set_requested_suffix(suf)
|
|
SuffixP suf;
|
|
{
|
|
if (requested_suffix == NULL)
|
|
{
|
|
switch (product.value->value)
|
|
{
|
|
case GOAL_I:
|
|
requested_suffix= suf;
|
|
break;
|
|
case GOAL_EXE:
|
|
if (driver.value != &xlint)
|
|
{
|
|
requested_suffix= &suffix.o; break;
|
|
}
|
|
/* Fall into */
|
|
case GOAL_L:
|
|
requested_suffix= &suffix.ln;
|
|
break;
|
|
case GOAL_O:
|
|
requested_suffix= &suffix.o;
|
|
break;
|
|
case GOAL_S:
|
|
requested_suffix= &suffix.s;
|
|
break;
|
|
}
|
|
}
|
|
} /* set_requested_suffix */
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Remove the infiles compiled for ld from the delete list.
|
|
* This is used if ld fails since we want to preseve the intermediate file
|
|
* then.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
do_not_unlink_ld_infiles()
|
|
{
|
|
register ListP infile;
|
|
register ListP to_unlink;
|
|
|
|
for (infile= infile_o; infile != NULL; infile= infile->next)
|
|
{
|
|
for ( to_unlink= files_to_unlink;
|
|
to_unlink != NULL;
|
|
to_unlink= to_unlink->next)
|
|
{
|
|
if (to_unlink->value && infile->value &&
|
|
(strcmp(to_unlink->value, infile->value)==0))
|
|
{
|
|
to_unlink->value= NULL;
|
|
goto found_it;
|
|
}
|
|
}
|
|
found_it: ;
|
|
}
|
|
}
|