aboutsummaryrefslogtreecommitdiff
path: root/ld/ldmain.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ldmain.c')
-rw-r--r--ld/ldmain.c211
1 files changed, 120 insertions, 91 deletions
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 8705bcb..4258b52 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -101,6 +101,10 @@ boolean write_map;
int unix_relocate;
+#ifdef GNU960
+/* Indicates whether output file will be b.out (default) or coff */
+enum target_flavour_enum output_flavor = BFD_BOUT_FORMAT;
+#endif
@@ -139,11 +143,23 @@ main (argc, argv)
output_filename = "a.out";
#ifdef GNU960
- check_v960( argc, argv );
+ {
+ int i;
+
+ check_v960( argc, argv );
+ emulation = GLD960_EMULATION_NAME;
+ for ( i = 1; i < argc; i++ ){
+ if ( !strcmp(argv[i],"-Fcoff") ){
+ emulation = LNK960_EMULATION_NAME;
+ output_flavor = BFD_COFF_FORMAT;
+ break;
+ }
+ }
+ }
+#else
+ emulation = (char *) getenv(EMULATION_ENVIRON);
#endif
- emulation = (char *) getenv(EMULATION_ENVIRON);
-
/* Initialize the data about options. */
trace_files = false;
@@ -168,17 +184,13 @@ main (argc, argv)
config.magic_demand_paged = true ;
config.make_executable = true;
-
-#ifdef GNU960
- ldemul_choose_mode(LNK960_EMULATION_NAME);
-#else
if (emulation == (char *)NULL) {
emulation= DEFAULT_EMULATION;
}
ldemul_choose_mode(emulation);
-#endif
+
default_target = ldemul_choose_target();
@@ -239,7 +251,7 @@ Q_read_entry_symbols (desc, entry)
struct lang_input_statement_struct *entry;
{
if (entry->asymbols == (asymbol **)NULL) {
- size_t table_size = get_symtab_upper_bound(desc);
+ bfd_size_type table_size = get_symtab_upper_bound(desc);
entry->asymbols = (asymbol **)ldmalloc(table_size);
entry->symbol_count = bfd_canonicalize_symtab(desc, entry->asymbols) ;
@@ -300,95 +312,102 @@ Q_enter_global_ref (nlist_p)
ASSERT(sym->udata == 0);
- /* Just place onto correct chain */
- if (flag_is_common(this_symbol_flags)) {
- /* If we have a definition of this symbol already then
- * this common turns into a reference. Also we only
- * ever point to the largest common, so if we
- * have a common, but it's bigger that the new symbol
- * the turn this into a reference too.
- */
- if (sp->sdefs_chain)
- {
- /* This is a common symbol, but we already have a definition
- for it, so just link it into the ref chain as if
- it were a reference
- */
- refize(sp, nlist_p);
- }
- else if (sp->scoms_chain) {
- /* If we have a previous common, keep only the biggest */
- if ( (*(sp->scoms_chain))->value > sym->value) {
- /* other common is bigger, throw this one away */
- refize(sp, nlist_p);
+ if (flag_is_constructor(this_symbol_flags)) {
+ /* Just remeber the name, do it once per name by placing it as if
+ it were a zero sized common. The next ref */
+ ldlang_add_constructor(sp);
+
+ }
+ else {
+ if (flag_is_common(this_symbol_flags)) {
+ /* If we have a definition of this symbol already then
+ * this common turns into a reference. Also we only
+ * ever point to the largest common, so if we
+ * have a common, but it's bigger that the new symbol
+ * the turn this into a reference too.
+ */
+ if (sp->sdefs_chain)
+ {
+ /* This is a common symbol, but we already have a definition
+ for it, so just link it into the ref chain as if
+ it were a reference
+ */
+ refize(sp, nlist_p);
+ }
+ else if (sp->scoms_chain) {
+ /* If we have a previous common, keep only the biggest */
+ if ( (*(sp->scoms_chain))->value > sym->value) {
+ /* other common is bigger, throw this one away */
+ refize(sp, nlist_p);
+ }
+ else if (sp->scoms_chain != nlist_p) {
+ /* other common is smaller, throw that away */
+ refize(sp, sp->scoms_chain);
+ sp->scoms_chain = nlist_p;
+ }
}
- else if (sp->scoms_chain != nlist_p) {
- /* other common is smaller, throw that away */
- refize(sp, sp->scoms_chain);
+ else {
+ /* This is the first time we've seen a common, so
+ * remember it - if it was undefined before, we know it's defined now
+ */
+ if (sp->srefs_chain)
+ undefined_global_sym_count--;
+
+ commons_pending++;
sp->scoms_chain = nlist_p;
}
}
- else {
- /* This is the first time we've seen a common, so
- * remember it - if it was undefined before, we know it's defined now
- */
- if (sp->srefs_chain)
- undefined_global_sym_count--;
- commons_pending++;
- sp->scoms_chain = nlist_p;
- }
- }
-
- else if (flag_is_defined(this_symbol_flags)) {
- /* This is the definition of a symbol, add to def chain */
- if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section) {
- /* Multiple definition */
- asymbol *sy = *(sp->sdefs_chain);
- lang_input_statement_type *stat = (lang_input_statement_type *) sy->the_bfd->usrdata;
- lang_input_statement_type *stat1 = (lang_input_statement_type *) sym->the_bfd->usrdata;
- asymbol ** stat1_symbols = stat1 ? stat1->asymbols: 0;
- asymbol ** stat_symbols = stat ? stat->asymbols:0;
+ else if (flag_is_defined(this_symbol_flags)) {
+ /* This is the definition of a symbol, add to def chain */
+ if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section) {
+ /* Multiple definition */
+ asymbol *sy = *(sp->sdefs_chain);
+ lang_input_statement_type *stat = (lang_input_statement_type *) sy->the_bfd->usrdata;
+ lang_input_statement_type *stat1 = (lang_input_statement_type *) sym->the_bfd->usrdata;
+ asymbol ** stat1_symbols = stat1 ? stat1->asymbols: 0;
+ asymbol ** stat_symbols = stat ? stat->asymbols:0;
- multiple_def_count++;
- info("%C: multiple definition of `%T'\n",
- sym->the_bfd,
- sym->section,
- stat1_symbols,
- sym->value,
- sym);
+ multiple_def_count++;
+ info("%C: multiple definition of `%T'\n",
+ sym->the_bfd,
+ sym->section,
+ stat1_symbols,
+ sym->value,
+ sym);
- info("%C: first seen here\n",
- sy->the_bfd,
- sy->section,
- stat_symbols,
- sy->value);
+ info("%C: first seen here\n",
+ sy->the_bfd,
+ sy->section,
+ stat_symbols,
+ sy->value);
+ }
+ else {
+ sym->udata =(PTR)( sp->sdefs_chain);
+ sp->sdefs_chain = nlist_p;
+ }
+ /* A definition overrides a common symbol */
+ if (sp->scoms_chain) {
+ refize(sp, sp->scoms_chain);
+ sp->scoms_chain = 0;
+ commons_pending--;
+ }
+ else if (sp->srefs_chain) {
+ /* If previously was undefined, then remember as defined */
+ undefined_global_sym_count--;
+ }
}
else {
- sym->udata =(PTR)( sp->sdefs_chain);
- sp->sdefs_chain = nlist_p;
- }
- /* A definition overrides a common symbol */
- if (sp->scoms_chain) {
- refize(sp, sp->scoms_chain);
- sp->scoms_chain = 0;
- commons_pending--;
- }
- else if (sp->srefs_chain) {
- /* If previously was undefined, then remember as defined */
- undefined_global_sym_count--;
- }
- }
- else {
- if (sp->scoms_chain == (asymbol **)NULL
- && sp->srefs_chain == (asymbol **)NULL
- && sp->sdefs_chain == (asymbol **)NULL) {
- /* And it's the first time we've seen it */
- undefined_global_sym_count++;
+ if (sp->scoms_chain == (asymbol **)NULL
+ && sp->srefs_chain == (asymbol **)NULL
+ && sp->sdefs_chain == (asymbol **)NULL) {
+ /* And it's the first time we've seen it */
+ undefined_global_sym_count++;
- }
+ }
- refize(sp, nlist_p);
+ refize(sp, nlist_p);
+ }
}
ASSERT(sp->sdefs_chain == 0 || sp->scoms_chain == 0);
@@ -418,10 +437,17 @@ lang_input_statement_type *entry;
{
asymbol *p = *q;
- if (flag_is_undefined_or_global_or_common(p->flags))
+ if (flag_is_undefined_or_global_or_common_or_constructor(p->flags))
{
Q_enter_global_ref(q);
}
+ if (p->flags & BSF_INDIRECT) {
+ add_indirect(q);
+ }
+
+ if (p->flags & BSF_WARNING) {
+ add_warning(p);
+ }
ASSERT(p->flags != 0);
}
}
@@ -463,9 +489,12 @@ bfd_format format;
{
boolean retval;
- if ((bfd_check_format(abfd,format) == true) && BFD_COFF_FILE_P(abfd)) {
- return true;
+ if ((bfd_check_format(abfd,format) == true)
+ && (abfd->xvec->flavour == output_flavor) ){
+ return true;
}
+
+
return false;
}
#endif
@@ -525,7 +554,7 @@ decode_library_subfile (library_entry, subfile_offset)
bfd *subfile_offset;
{
register struct lang_input_statement_struct *subentry;
- subentry = (struct lang_input_statement_struct *) ldmalloc (sizeof (struct lang_input_statement_struct));
+ subentry = (struct lang_input_statement_struct *) ldmalloc ((bfd_size_type)(sizeof (struct lang_input_statement_struct)));
subentry->filename = subfile_offset -> filename;
subentry->local_sym_name = subfile_offset->filename;
subentry->asymbols = 0;