diff --git a/ld/ChangeLog b/ld/ChangeLog index 5ae653f02f..da96cc769d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,10 @@ Sat Dec 11 14:43:44 1993 Ian Lance Taylor (ian@deneb.cygnus.com) + Made many changes to eliminate gcc warnings. Made various + cosmetic changes, declared various things in header files, removed + various extern declarations from .c files. No substantive + changes. + * ldlang.c (lang_process): Ifdef out final call to lang_size_sections again (reverting change of Nove 2), since it breaks the Sun4 linker. diff --git a/ld/ldctor.c b/ld/ldctor.c new file mode 100644 index 0000000000..2a7e9b0135 --- /dev/null +++ b/ld/ldctor.c @@ -0,0 +1,155 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * By steve chamberlain + * steve@cygnus.com + */ + +#include "bfd.h" +#include "sysdep.h" +#include "ld.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldsym.h" +#include "ldmisc.h" +#include "ldgram.h" + +/* exported list of statements needed to handle constructors */ +lang_statement_list_type constructor_list; + + + +typedef struct constructor_list +{ + CONST char *name; + struct constructor_list *next; +} constructor_list_type; + +static constructor_list_type *constructor_name_list; + +static void +add_constructor_name (name) + CONST char *name; +{ + register constructor_list_type *ptr = constructor_name_list; + for (; ptr != (constructor_list_type *)NULL; ptr = ptr->next) { + if (strcmp (ptr->name, name) == 0) + return; + } + + /* There isn't an entry, so add one */ + ptr = (constructor_list_type *) ldmalloc (sizeof(constructor_list_type)); + ptr->next = constructor_name_list; + ptr->name = name; + constructor_name_list = ptr; +} + +void +ldlang_add_constructor (name) + ldsym_type *name; +{ + if (name->flags & SYM_CONSTRUCTOR) return; + add_constructor_name (name->name); + name->flags |= SYM_CONSTRUCTOR; +} + + +/* this function looks through the sections attached to the supplied + bfd to see if any of them are magical constructor sections. If so + their names are remembered and added to the list of constructors */ + +void +ldlang_check_for_constructors (entry) + struct lang_input_statement_struct *entry; +{ + asection *section; + + for (section = entry->the_bfd->sections; + section != (asection *)NULL; + section = section->next) + { + if (section->flags & SEC_CONSTRUCTOR) + add_constructor_name (section->name); + } +} + + +/* run through the symbol table, find all the symbols which are + constructors and for each one, create statements to do something + like.. + + for something like "__CTOR_LIST__, foo" in the assembler + + __CTOR_LIST__ = . ; + LONG(__CTOR_LIST_END - . / 4 - 2) + *(foo) + __CTOR_LIST_END= . + + Put these statements onto a special list. + +*/ + + +void +find_constructors () +{ + lang_statement_list_type *old = stat_ptr; + constructor_list_type *p = constructor_name_list; + stat_ptr = & constructor_list; + lang_list_init(stat_ptr); + while (p != (constructor_list_type *)NULL) + { + /* Have we already done this one ? */ + CONST char *name = p->name; + ldsym_type *lookup = ldsym_get_soft(name); + + /* If ld is invoked from collect, then the constructor list + will already have been defined, so don't do it again. */ + + if (lookup->sdefs_chain == (asymbol **)NULL) + { + size_t len = strlen(name); + char *end = ldmalloc(len+3); + strcpy(end, name); + strcat(end,"$e"); + + lang_add_assignment + ( exp_assop('=',name, exp_nameop(NAME,"."))); + + lang_add_data + (LONG, exp_binop('-', + exp_binop ( '/', + exp_binop ( '-', + exp_nameop(NAME, end), + exp_nameop(NAME,".")), + exp_intop(4)), + + exp_intop(2))); + + + lang_add_wild(name, (char *)NULL); + lang_add_data(LONG, exp_intop(0)); + lang_add_assignment + (exp_assop('=', end, exp_nameop(NAME,"."))); + } + p = p->next; + } + stat_ptr = old; +} + diff --git a/ld/lderror.c b/ld/lderror.c index b43282d225..83eded5f69 100644 --- a/ld/lderror.c +++ b/ld/lderror.c @@ -1,4 +1,23 @@ -#include "bfd.h" +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include #include "sysdep.h" #include "../bfd/seclet.h" #include "ld.h" @@ -6,11 +25,8 @@ #define MAX_ERRORS_IN_A_ROW 5 -extern ld_config_type config; - extern bfd_error_vector_type bfd_error_vector; - /* BFD has failed to link something, give a better error message */ static void @@ -64,15 +80,12 @@ ld_reloc_truncated (relent, seclet) CONST arelent *relent; bfd_seclet_type *seclet; { - asymbol *s = *(relent->sym_ptr_ptr); asection *section = seclet->u.indirect.section; bfd *abfd = section->owner; einfo("%X%C: relocation truncated to fit %R\n", abfd, section, seclet->u.indirect.symbols, relent->address, relent); - } - void init_bfd_error_vector () diff --git a/ld/ldexp.c b/ld/ldexp.c index b099037a89..15c2b556c9 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -32,23 +32,13 @@ contains a value, a section to which it is relative and a valid bit. #include "sysdep.h" #include "ld.h" +#include "ldsym.h" #include "ldmain.h" #include "ldmisc.h" #include "ldexp.h" #include "ldgram.h" -#include "ldsym.h" #include "ldlang.h" -extern bfd *output_bfd; -extern bfd_size_type largest_section; -extern lang_statement_list_type file_chain; -extern ld_config_type config; - -extern lang_input_statement_type *script_file; - extern lang_output_section_statement_type *abs_output_section; -extern bfd_vma print_dot; - - static void exp_print_token (code) token_code_type code; @@ -139,10 +129,10 @@ check (os, name, op) CONST char *op; { if (os == (lang_output_section_statement_type *)NULL) { - einfo("%F%P %s uses undefined section %s\n", op, name); + einfo("%F%P: %s uses undefined section %s\n", op, name); } if (os->processed == false) { - einfo("%F%P %s forward reference of section %s\n",op, name); + einfo("%F%P: %s forward reference of section %s\n",op, name); } } @@ -219,7 +209,7 @@ fold_binary (tree, current_section, allocation_done, dot, dotp) /* Mod, both absolule*/ if (other.value == 0) { - einfo("%F%S % by zero\n"); + einfo("%F%S %% by zero\n"); } result.value = (int)result.value % (int)other.value; break; @@ -338,7 +328,7 @@ fold_name (tree, current_section, allocation_done, dot) } } if (result.valid == false) { - einfo("%F%S: undefined symbol `%s' referenced in expression.\n", + einfo("%F%S: undefined symbol `%s' referenced in expression\n", tree->name.name); } @@ -566,7 +556,7 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp) result = fold_name(tree, current_section, allocation_done, dot); break; default: - einfo("%F%S Need more of these %d\n",tree->type.node_class ); + einfo("%F%S need more of these %d\n",tree->type.node_class ); } } @@ -793,7 +783,7 @@ exp_get_vma (tree, def, name, allocation_done) abs_output_section, allocation_done); if (r.valid == false && name) { - einfo("%F%S Nonconstant expression for %s\n",name); + einfo("%F%S nonconstant expression for %s\n",name); } return r.value; } diff --git a/ld/ldfile.c b/ld/ldfile.c index f68ed7dc24..4c4af01212 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -26,23 +26,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "sysdep.h" - +#include "ld.h" #include "ldmisc.h" +#include "ldexp.h" #include "ldlang.h" #include "ldfile.h" +#include "ldsym.h" +#include "ldmain.h" +#include "ldlex.h" + #include -/* EXPORT */ + char *ldfile_input_filename; CONST char * ldfile_output_machine_name =""; unsigned long ldfile_output_machine; enum bfd_architecture ldfile_output_architecture; -/* IMPORT */ - -extern boolean had_script; -extern boolean trace_file_tries; - - #ifdef VMS char *slash = ""; #else @@ -93,7 +92,7 @@ lang_input_statement_type *entry; { entry->the_bfd = bfd_openr(attempt, entry->target); if (trace_file_tries == true ) { - info("attempt to open %s %s\n", attempt, + info_msg ("attempt to open %s %s\n", attempt, (entry->the_bfd == (bfd *)NULL) ? "failed" : "succeeded" ); } return entry->the_bfd; @@ -197,9 +196,9 @@ char *exten; result = fopen(name, "r"); if (trace_file_tries == true) { if (result == (FILE *)NULL) { - info("can't find "); + info_msg ("cannot find "); } - info("%s\n",name); + info_msg ("%s\n",name); } if (result != (FILE *)NULL) { return result; @@ -210,9 +209,9 @@ char *exten; result = fopen(buff, "r"); if (trace_file_tries == true) { if (result == (FILE *)NULL) { - info("can't find "); + info_msg ("cannot find "); } - info("%s\n", buff); + info_msg ("%s\n", buff); } } return result; @@ -221,8 +220,8 @@ char *exten; /* Try to open NAME; if that fails, look for it in any directories specified with -L, without and with EXTEND apppended. */ -static FILE * -find_a_name(name, extend) +FILE * +ldfile_find_command_file(name, extend) char *name; char *extend; { @@ -250,10 +249,10 @@ ldfile_open_command_file(name) char *name; { FILE *ldlex_input_stack; - ldlex_input_stack = find_a_name(name, ""); + ldlex_input_stack = ldfile_find_command_file(name, ""); if (ldlex_input_stack == (FILE *)NULL) { - einfo("%P%F: cannot open load script file %s: %E\n",name); + einfo("%P%F: cannot open linker script file %s: %E\n",name); } lex_push_file(ldlex_input_stack, name); @@ -361,6 +360,6 @@ ldfile_set_output_arch (string) ldfile_output_machine_name = arch->printable_name; } else { - einfo("%P%F: Can't represent machine `%s'\n", string); + einfo("%P%F: cannot represent machine `%s'\n", string); } } diff --git a/ld/ldgram.y b/ld/ldgram.y index 3ff91d78fd..d5726d1212 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -34,16 +34,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ldemul.h" #include "ldfile.h" #include "ldmisc.h" +#include "ldsym.h" +#include "ldmain.h" #include "mri.h" +#include "ldlex.h" #define YYDEBUG 1 -extern unsigned int lineno; -extern boolean trace_file_tries; -extern boolean trace_files; -extern boolean write_map; -extern int g_switch_value; -extern int hex_mode; static int typebits; strip_symbols_type strip_symbols=STRIP_NONE; discard_locals_type discard_locals=DISCARD_NONE; @@ -53,22 +50,6 @@ static char *dirlist_ptr; lang_memory_region_type *region; -lang_memory_region_type *lang_memory_region_lookup(); -lang_output_section_statement_type *lang_output_section_statement_lookup(); -etree_type *lang_atin(); -#ifdef __STDC__ - -void lang_add_data(int type, union etree_union *exp); -void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, int flags, bfd_vma block_value,etree_type*,etree_type*, etree_type*); - -#else - -void lang_add_data(); -void lang_enter_output_section_statement(); - -#endif /* __STDC__ */ - -extern args_type command_line; char *current_file; boolean ldgram_want_filename = true; boolean had_script = false; @@ -76,7 +57,6 @@ boolean force_make_executable = false; boolean ldgram_in_script = false; boolean ldgram_had_equals = false; -/* LOCALS */ #define ERROR_NAME_MAX 20 @@ -153,6 +133,7 @@ static int error_index; %token LENGTH CREATE_OBJECT_SYMBOLS INPUT OUTPUT CONSTRUCTORS %token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD AT %token OPTION_Qy OPTION_Y OPTION_dn OPTION_call_shared OPTION_non_shared +%token OPTION_Oval %token OPTION_YP %type assign_op @@ -163,10 +144,6 @@ static int error_index; %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE -%{ -extern ld_config_type config; -%} - %% file: command_line { lang_final(); }; @@ -391,6 +368,7 @@ command_line_option: | OPTION_dn | OPTION_non_shared | OPTION_call_shared + | OPTION_Oval | OPTION_YP { dirlist_ptr = $1; diff --git a/ld/ldindr.c b/ld/ldindr.c index f52c950cfb..88152ebaba 100644 --- a/ld/ldindr.c +++ b/ld/ldindr.c @@ -43,10 +43,9 @@ #include "sysdep.h" #include "ld.h" #include "ldsym.h" +#include "ldmain.h" #include "ldmisc.h" - - static asymbol ** move_it (a_list, b_list) asymbol **a_list; @@ -90,7 +89,6 @@ void add_indirect (ptr) asymbol **ptr; { - asymbol **p; ldsym_type *lgs = ldsym_get((*ptr)->name); ldsym_type *new = ldsym_get(((asymbol *)((*ptr)->value))->name); diff --git a/ld/ldlang.c b/ld/ldlang.c index a1e4293b38..6635ca873e 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -21,17 +21,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "sysdep.h" #include "ld.h" -#include "ldmain.h" #include "ldsym.h" +#include "ldmain.h" #include "ldgram.h" #include "ldwarn.h" -#include "ldlang.h" #include "ldexp.h" +#include "ldlang.h" #include "ldemul.h" #include "ldlex.h" #include "ldmisc.h" #include "ldindr.h" #include "ldctor.h" +#include "ldfile.h" +#include "relax.h" /* FORWARDS */ static void print_statements PARAMS ((void)); @@ -54,9 +56,6 @@ static lang_statement_list_type input_file_chain; stuff to the data section without pain */ static lang_statement_list_type end_of_data_section_statement_list; -/* List of statements needed to handle constructors */ -extern lang_statement_list_type constructor_list; - static boolean placed_commons = false; static lang_output_section_statement_type *default_common_section; static boolean map_option_f; @@ -65,8 +64,7 @@ static lang_input_statement_type *first_file; static lang_statement_list_type lang_output_section_statement; static CONST char *current_target; static CONST char *output_target; -static size_t longest_section_name = 8; -static section_userdata_type common_section_userdata; +static int longest_section_name = 8; static lang_statement_list_type statement_list; /* EXPORTS */ @@ -84,23 +82,6 @@ boolean had_output_filename = false; boolean lang_float_flag = false; boolean delete_output_file_on_failure = false; -/* IMPORTS */ -extern char *default_target; - -extern CONST char *output_filename; -extern char *current_file; -extern bfd *output_bfd; -extern enum bfd_architecture ldfile_output_architecture; -extern unsigned long ldfile_output_machine; -extern char *ldfile_output_machine_name; -extern ldsym_type *symbol_head; -extern unsigned int commons_pending; -extern args_type command_line; -extern ld_config_type config; -extern boolean write_map; -extern int g_switch_value; - - etree_type *base; /* Relocation base - or null */ @@ -350,7 +331,6 @@ void lang_add_keepsyms_file (filename) CONST char *filename; { - extern strip_symbols_type strip_symbols; if (keepsyms_file != 0) info_msg ("%X%P: error: duplicated keep-symbols-file value\n"); keepsyms_file = filename; @@ -541,7 +521,8 @@ lang_map () print_address (m->current - m->origin); print_space(); if (m->old_length) - fprintf(config.map_file," %2d%% ", ( m->current - m->origin) * 100 / m->old_length); + fprintf (config.map_file, " %2d%% ", + (int) ((m->current - m->origin) * 100 / m->old_length)); print_flags (&m->flags); fprintf (config.map_file, "\n"); } @@ -783,9 +764,6 @@ static bfd * open_output (name) CONST char *CONST name; { - extern unsigned long ldfile_output_machine; - extern enum bfd_architecture ldfile_output_architecture; - bfd *output; if (output_target == (char *) NULL) @@ -2362,7 +2340,7 @@ void lang_enter_output_section_statement (output_section_statement_name, address_exp, flags, block_value, align, subalign, base) - char *output_section_statement_name; + const char *output_section_statement_name; etree_type * address_exp; int flags; bfd_vma block_value; @@ -2441,7 +2419,6 @@ DEFUN (create_symbol, (name, flags, section), flagword flags AND asection * section) { - extern lang_input_statement_type *script_file; asymbol **def_ptr = (asymbol **) stat_alloc ((bfd_size_type) (sizeof (asymbol **))); /* Add this definition to script file */ diff --git a/ld/ldlang.h b/ld/ldlang.h index ad0fe6b5cb..7df1189c58 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -1,6 +1,5 @@ -/* ldlang.h - - - Copyright (C) 1991 Free Software Foundation, Inc. +/* ldlang.h - linker command language support + Copyright 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -18,39 +17,44 @@ along with GLD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef LDLANG_H +#define LDLANG_H -typedef enum { +typedef enum +{ lang_input_file_is_l_enum, lang_input_file_is_symbols_only_enum, lang_input_file_is_marker_enum, lang_input_file_is_fake_enum, lang_input_file_is_search_file_enum, - lang_input_file_is_file_enum } lang_input_file_enum_type; + lang_input_file_is_file_enum +} lang_input_file_enum_type; typedef unsigned short fill_type; -typedef struct statement_list { +typedef struct statement_list +{ union lang_statement_union *head; union lang_statement_union **tail; } lang_statement_list_type; - - -typedef struct memory_region_struct { +typedef struct memory_region_struct +{ char *name; struct memory_region_struct *next; bfd_vma origin; - bfd_offset length; + bfd_size_type length; bfd_vma current; + bfd_size_type old_length; int flags; boolean had_full_message; - } lang_memory_region_type ; typedef struct lang_statement_header_struct - { - union lang_statement_union *next; - enum statement_enum { +{ + union lang_statement_union *next; + enum statement_enum + { lang_output_section_statement_enum, lang_assignment_statement_enum, lang_input_statement_enum, @@ -65,66 +69,77 @@ typedef struct lang_statement_header_struct lang_padding_statement_enum, lang_afile_asection_pair_statement_enum, - lang_constructors_statement_enum - } type; - - } lang_statement_header_type; + lang_constructors_statement_enum + } type; +} lang_statement_header_type; typedef struct - { - lang_statement_header_type header; - union etree_union *exp; - } lang_assignment_statement_type; - - -typedef struct lang_target_statement_struct { +{ lang_statement_header_type header; - CONST char *target; + union etree_union *exp; +} lang_assignment_statement_type; + + +typedef struct lang_target_statement_struct +{ + lang_statement_header_type header; + const char *target; } lang_target_statement_type; -typedef struct lang_output_statement_struct { +typedef struct lang_output_statement_struct +{ lang_statement_header_type header; - CONST char *name; + const char *name; } lang_output_statement_type; typedef struct lang_output_section_statement_struct - { - lang_statement_header_type header; - union etree_union *addr_tree; - lang_statement_list_type children; - CONST char *memspec; - union lang_statement_union *next; - CONST char *name; - unsigned long subsection_alignment; - boolean processed; +{ + lang_statement_header_type header; + union etree_union *addr_tree; + lang_statement_list_type children; + const char *memspec; + union lang_statement_union *next; + const char *name; + + boolean processed; - asection *bfd_section; - int flags; - struct memory_region_struct *region; - size_t block_value; - fill_type fill; - } lang_output_section_statement_type; + asection *bfd_section; + int flags; /* Or together of all input sections */ + int loadable; /* set from NOLOAD flag in script */ + struct memory_region_struct *region; + size_t block_value; + fill_type fill; + + int subsection_alignment; /* alignment of components */ + int section_alignment; /* alignment of start of section */ + + union etree_union *load_base; +} lang_output_section_statement_type; -typedef struct { +typedef struct +{ lang_statement_header_type header; } lang_common_statement_type; -typedef struct { +typedef struct +{ lang_statement_header_type header; } lang_object_symbols_statement_type; -typedef struct { +typedef struct +{ lang_statement_header_type header; fill_type fill; int size; asection *output_section; } lang_fill_statement_type; -typedef struct { +typedef struct +{ lang_statement_header_type header; unsigned int type; union etree_union *exp; @@ -137,67 +152,69 @@ typedef struct { typedef struct lang_input_statement_struct - { - lang_statement_header_type header; - /* Name of this file. */ - CONST char *filename; - /* Name to use for the symbol giving address of text start */ - /* Usually the same as filename, but for a file spec'd with -l - this is the -l switch itself rather than the filename. */ - CONST char *local_sym_name; +{ + lang_statement_header_type header; + /* Name of this file. */ + const char *filename; + /* Name to use for the symbol giving address of text start */ + /* Usually the same as filename, but for a file spec'd with -l + this is the -l switch itself rather than the filename. */ + const char *local_sym_name; - bfd *the_bfd; + bfd *the_bfd; - boolean closed; - file_ptr passive_position; + boolean closed; + file_ptr passive_position; - /* Symbol table of the file. */ - asymbol **asymbols; - unsigned int symbol_count; + /* Symbol table of the file. */ + asymbol **asymbols; + unsigned int symbol_count; - /* For library members only */ + /* For library members only */ - /* For a library, points to chain of entries for the library members. */ - struct lang_input_statement_struct *subfiles; - /* For a library member, offset of the member within the archive. - Zero for files that are not library members. */ - /* int starting_offset;*/ - /* Size of contents of this file, if library member. */ - bfd_size_type total_size; - /* For library member, points to the library's own entry. */ - struct lang_input_statement_struct *superfile; - /* For library member, points to next entry for next member. */ - struct lang_input_statement_struct *chain; - /* Point to the next file - whatever it is, wanders up and down - archives */ - - union lang_statement_union *next; - /* Point to the next file, but skips archive contents */ - union lang_statement_union *next_real_file; - - boolean is_archive; - - /* 1 means search a set of directories for this file. */ - boolean search_dirs_flag; - - /* 1 means this is base file of incremental load. - Do not load this file's text or data. - Also default text_start to after this file's bss. */ - - boolean just_syms_flag; - - boolean loaded; - - - /* unsigned int globals_in_this_file;*/ - CONST char *target; - boolean real; - - asection *common_section; - asection *common_output_section; - } lang_input_statement_type; + /* For a library, points to chain of entries for the library members. */ + struct lang_input_statement_struct *subfiles; -typedef struct { + /* Size of contents of this file, if library member. */ + bfd_size_type total_size; + + /* For library member, points to the library's own entry. */ + struct lang_input_statement_struct *superfile; + + /* For library member, points to next entry for next member. */ + struct lang_input_statement_struct *chain; + + /* Point to the next file - whatever it is, wanders up and down + archives */ + + union lang_statement_union *next; + /* Point to the next file, but skips archive contents */ + union lang_statement_union *next_real_file; + + boolean is_archive; + + /* 1 means search a set of directories for this file. */ + boolean search_dirs_flag; + + /* 1 means this is base file of incremental load. + Do not load this file's text or data. + Also default text_start to after this file's bss. */ + + boolean just_syms_flag; + + boolean loaded; + + + /* unsigned int globals_in_this_file;*/ + const char *target; + boolean real; + asection *common_section; + asection *common_output_section; + boolean complained; +} lang_input_statement_type; + +typedef struct +{ lang_statement_header_type header; asection *section; lang_input_statement_type *ifile; @@ -205,26 +222,30 @@ typedef struct { } lang_input_section_type; -typedef struct { +typedef struct +{ lang_statement_header_type header; asection *section; union lang_statement_union *file; } lang_afile_asection_pair_statement_type; -typedef struct lang_wild_statement_struct { +typedef struct lang_wild_statement_struct +{ lang_statement_header_type header; - CONST char *section_name; - CONST char *filename; + const char *section_name; + const char *filename; lang_statement_list_type children; } lang_wild_statement_type; -typedef struct lang_address_statement_struct { +typedef struct lang_address_statement_struct +{ lang_statement_header_type header; - CONST char *section_name; + const char *section_name; union etree_union *address; } lang_address_statement_type; -typedef struct { +typedef struct +{ lang_statement_header_type header; bfd_vma output_offset; size_t size; @@ -233,112 +254,127 @@ typedef struct { } lang_padding_statement_type; typedef union lang_statement_union - { - lang_statement_header_type header; - union lang_statement_union *next; - lang_wild_statement_type wild_statement; - lang_data_statement_type data_statement; - lang_address_statement_type address_statement; - lang_output_section_statement_type output_section_statement; - lang_afile_asection_pair_statement_type afile_asection_pair_statement; - lang_assignment_statement_type assignment_statement; - lang_input_statement_type input_statement; - lang_target_statement_type target_statement; - lang_output_statement_type output_statement; - lang_input_section_type input_section; - lang_common_statement_type common_statement; - lang_object_symbols_statement_type object_symbols_statement; - lang_fill_statement_type fill_statement; - lang_padding_statement_type padding_statement; - } lang_statement_union_type; +{ + lang_statement_header_type header; + union lang_statement_union *next; + lang_wild_statement_type wild_statement; + lang_data_statement_type data_statement; + lang_address_statement_type address_statement; + lang_output_section_statement_type output_section_statement; + lang_afile_asection_pair_statement_type afile_asection_pair_statement; + lang_assignment_statement_type assignment_statement; + lang_input_statement_type input_statement; + lang_target_statement_type target_statement; + lang_output_statement_type output_statement; + lang_input_section_type input_section; + lang_common_statement_type common_statement; + lang_object_symbols_statement_type object_symbols_statement; + lang_fill_statement_type fill_statement; + lang_padding_statement_type padding_statement; +} lang_statement_union_type; +extern bfd_size_type largest_section; +extern lang_output_section_statement_type *abs_output_section; +extern lang_input_statement_type *script_file; +extern boolean lang_has_input_file; +extern boolean relaxing; +extern etree_type *base; +extern lang_statement_list_type *stat_ptr; +extern boolean delete_output_file_on_failure; +extern lang_output_section_statement_type *create_object_symbols; +extern void lang_init PARAMS ((void)); +extern struct memory_region_struct *lang_memory_region_lookup + PARAMS ((const char *const)); +extern void lang_map PARAMS ((void)); +extern void lang_set_flags PARAMS ((int *, const char *)); +extern void lang_add_output PARAMS ((const char *, int from_script)); +extern void lang_enter_output_section_statement + PARAMS ((const char *output_section_statement_name, + etree_type * address_exp, + int flags, + bfd_vma block_value, + etree_type *align, + etree_type *subalign, + etree_type *base)); +extern void lang_final PARAMS ((void)); +extern struct symbol_cache_entry *create_symbol + PARAMS ((const char *, unsigned int, struct sec *)); +extern void lang_process PARAMS ((void)); +extern void lang_section_start PARAMS ((const char *, union etree_union *)); +extern void lang_add_entry PARAMS ((const char *)); +extern void lang_add_target PARAMS ((const char *)); +extern void lang_add_wild PARAMS ((const char *const , const char *const)); +extern void lang_add_map PARAMS ((const char *)); +extern void lang_add_fill PARAMS ((int)); +extern void lang_add_assignment PARAMS ((union etree_union *)); +extern void lang_add_attribute PARAMS ((enum statement_enum)); +extern void lang_startup PARAMS ((const char *)); +extern void lang_float PARAMS ((enum bfd_boolean)); +extern void lang_leave_output_section_statement PARAMS ((bfd_vma, + const char *)); +extern void lang_abs_symbol_at_end_of PARAMS ((const char *, const char *)); +extern void lang_abs_symbol_at_beginning_of PARAMS ((const char *, + const char *)); +extern void lang_statement_append PARAMS ((struct statement_list *, + union lang_statement_union *, + union lang_statement_union **)); +extern void lang_for_each_file + PARAMS ((void (*dothis) (lang_input_statement_type *))); -PROTO(void,lang_init,(void)); -PROTO(struct memory_region_struct , - *lang_memory_region_lookup,(CONST - char *CONST)); - - -PROTO(void ,lang_map,(void)); -PROTO(void,lang_set_flags,(int *, CONST char *)); -PROTO(void,lang_add_output,(CONST char *)); - -PROTO(void,lang_final,(void)); -PROTO(struct symbol_cache_entry *,create_symbol,(CONST char *, unsigned int, struct sec *)); -PROTO(void ,lang_process,(void)); -PROTO(void ,lang_section_start,(CONST char *, union etree_union *)); -PROTO(void,lang_add_entry,(CONST char *)); -PROTO(void,lang_add_target,(CONST char *)); -PROTO(void,lang_add_wild,(CONST char *CONST , CONST char *CONST)); -PROTO(void,lang_add_map,(CONST char *)); -PROTO(void,lang_add_fill,(int)); -PROTO(void,lang_add_assignment,(union etree_union *)); -PROTO(void,lang_add_attribute,(enum statement_enum)); -PROTO(void,lang_startup,(CONST char *)); -PROTO(void,lang_float,(enum bfd_boolean)); -PROTO(void,lang_leave_output_section_statement,(bfd_vma, CONST char *)); -PROTO(void,lang_abs_symbol_at_end_of,(CONST char *, CONST char *)); -PROTO(void,lang_abs_symbol_at_beginning_of,(CONST char *, CONST char *)); -PROTO(void,lang_statement_append,(struct statement_list *, union lang_statement_union *, union lang_statement_union **)); -PROTO(void, lang_for_each_file,(void (*dothis)(lang_input_statement_type *))); - - -#define LANG_FOR_EACH_INPUT_STATEMENT(statement) \ +#define LANG_FOR_EACH_INPUT_STATEMENT(statement) \ extern lang_statement_list_type file_chain; \ lang_input_statement_type *statement; \ for (statement = (lang_input_statement_type *)file_chain.head;\ statement != (lang_input_statement_type *)NULL; \ statement = (lang_input_statement_type *)statement->next)\ -#define LANG_FOR_EACH_INPUT_SECTION(statement, abfd, section, x) \ - { extern lang_statement_list_type file_chain; \ - lang_input_statement_type *statement; \ - for (statement = (lang_input_statement_type *)file_chain.head;\ - statement != (lang_input_statement_type *)NULL; \ - statement = (lang_input_statement_type *)statement->next)\ - { \ - asection *section; \ - bfd *abfd = statement->the_bfd; \ - for (section = abfd->sections; \ - section != (asection *)NULL; \ - section = section->next) { \ - x; \ - } \ - } \ - } +#define LANG_FOR_EACH_INPUT_SECTION(statement, abfd, section, x) \ + { \ + extern lang_statement_list_type file_chain; \ + lang_input_statement_type *statement; \ + for (statement = (lang_input_statement_type *)file_chain.head; \ + statement != (lang_input_statement_type *)NULL; \ + statement = (lang_input_statement_type *)statement->next) \ + { \ + asection *section; \ + bfd *abfd = statement->the_bfd; \ + for (section = abfd->sections; \ + section != (asection *)NULL; \ + section = section->next) \ + { \ + x; \ + } \ + } \ + } #define LANG_FOR_EACH_OUTPUT_SECTION(section, x) \ - { extern bfd *output_bfd; \ - asection *section; \ - for (section = output_bfd->sections; \ - section != (asection *)NULL; \ - section = section->next) \ - { x; } \ - } + { \ + extern bfd *output_bfd; \ + asection *section; \ + for (section = output_bfd->sections; \ + section != (asection *)NULL; \ + section = section->next) \ + { \ + x; \ + } \ + } +extern void lang_process PARAMS ((void)); +extern void ldlang_add_file PARAMS ((lang_input_statement_type *)); +extern lang_output_section_statement_type *lang_output_section_find + PARAMS ((const char * const)); +extern lang_input_statement_type *lang_add_input_file + PARAMS ((const char *name, lang_input_file_enum_type file_type, + const char *target)); +extern void lang_add_keepsyms_file PARAMS ((const char *filename)); +extern lang_output_section_statement_type * + lang_output_section_statement_lookup PARAMS ((const char * const name)); +extern void ldlang_add_undef PARAMS ((const char *const name)); +extern void lang_add_output_format PARAMS ((const char *, int from_script)); +extern void lang_list_init PARAMS ((lang_statement_list_type*)); +extern void lang_add_data PARAMS ((int type, union etree_union *)); +extern void lang_for_each_statement PARAMS ((void (*func)())); +extern PTR stat_alloc PARAMS ((size_t size)); -PROTO(void, lang_process,(void)); -PROTO(void, ldlang_add_file,(lang_input_statement_type *)); - -PROTO(lang_output_section_statement_type - *,lang_output_section_find,(CONST char * CONST)); - -PROTO(lang_input_statement_type *, - lang_add_input_file,(CONST char *name, - lang_input_file_enum_type file_type, - CONST char *target)); -PROTO(lang_output_section_statement_type *, - lang_output_section_statement_lookup,(CONST char * CONST name)); - -PROTO(void, ldlang_add_undef,(CONST char *CONST name)); -PROTO(void, lang_add_output_format,(CONST char *)); - - -void EXFUN(lang_list_init,( lang_statement_list_type*)); - -void EXFUN(lang_add_data,(int type, union etree_union *)); - -void EXFUN(lang_for_each_statement,(void (*func)())); - -PTR EXFUN(stat_alloc,(size_t size)); +#endif diff --git a/ld/ldlex.h b/ld/ldlex.h index fe4e017f75..ed79934f8e 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -1,6 +1,5 @@ /* ldlex.h - - - Copyright (C) 1991 Free Software Foundation, Inc. + Copyright 1991, 1992 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -18,9 +17,31 @@ along with GLD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -PROTO(int, lex_input, (void)); -PROTO(void, lex_unput, (int)); -PROTO(int ,yywrap,(void)); -PROTO(void, parse_args,(int, char **)); -PROTO(void, parse_line,(char*)); +#ifndef LDLEX_H +#define LDLEX_H +#include + +extern int hex_mode; +extern unsigned int lineno; + +/* In ldlex.l. */ +extern int yylex PARAMS ((void)); +extern void lex_push_file PARAMS ((FILE *, char *)); +extern void lex_redirect PARAMS ((const char *)); +extern void ldlex_script PARAMS ((void)); +extern void ldlex_mri_script PARAMS ((void)); +extern void ldlex_defsym PARAMS ((void)); +extern void ldlex_expression PARAMS ((void)); +extern void ldlex_both PARAMS ((void)); +extern void ldlex_command PARAMS ((void)); +extern void ldlex_popstate PARAMS ((void)); + +/* In lexsup.c. */ +extern int lex_input PARAMS ((void)); +extern void lex_unput PARAMS ((int)); +extern int yywrap PARAMS ((void)); +extern void parse_args PARAMS ((int, char **)); +extern void parse_line PARAMS ((char*, int)); + +#endif diff --git a/ld/ldlex.l b/ld/ldlex.l index 19ded41e27..27be289f03 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -25,35 +25,37 @@ This was written by steve chamberlain #include +#include #include "bfd.h" +#include "ld.h" #include "ldgram.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldfile.h" int ldgram_in_defsym; -extern int ldgram_had_equals; -extern int ldgram_in_script; int hex_mode; -extern int fgetc(); -extern int yyparse(); - - char *buystring(); unsigned int lineno = 1; int old; -static comment(); - #undef YY_INPUT #define YY_INPUT(buf,result,max_size) yy_input(buf, &result, max_size) #undef YY_FATAL_ERROR -#define YY_FATAL_ERROR ; +#define YY_FATAL_ERROR(s) #define MAX_INCLUDE_DEPTH 10 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; char *file_name_stack[MAX_INCLUDE_DEPTH]; unsigned int include_stack_ptr = 0; +static YY_BUFFER_STATE yy_create_string_buffer PARAMS ((const char *string, + int size)); +static void yy_input PARAMS ((char *, int *result, int max_size)); +static void comment PARAMS ((void)); /* STATES COMMAND on command line @@ -159,6 +161,10 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] yylval.name = ".bss"; return OPTION_Texp; } +"-O"([0-9])+ { + yylval.integer = atoi (yytext + 2); + return OPTION_Oval; + } "-O"{FILENAME} { yylval.name = buystring(yytext+2); return OPTION_Texp; @@ -399,7 +405,6 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] [ \t] <> { - extern char *ldfile_input_filename; include_stack_ptr--; if (include_stack_ptr == 0) @@ -445,7 +450,7 @@ lex_push_file (file, name) BEGIN(SCRIPT); } -YY_BUFFER_STATE +static YY_BUFFER_STATE yy_create_string_buffer (string, size) CONST char *string; int size; @@ -557,6 +562,7 @@ ldlex_popstate () yy_start = *(--state_stack_p); } +static void yy_input(buf, result, max_size) char *buf; int *result; @@ -571,8 +577,8 @@ int max_size; } } -static -comment() +static void +comment () { int c; while (1) diff --git a/ld/ldmain.c b/ld/ldmain.c index 30baa964a6..8d50add079 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -23,11 +23,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include "ld.h" +#include "ldsym.h" #include "ldmain.h" #include "ldmisc.h" #include "ldwrite.h" #include "ldgram.h" -#include "ldsym.h" +#include "ldexp.h" #include "ldlang.h" #include "ldemul.h" #include "ldlex.h" @@ -44,19 +45,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -static char *get_emulation (); -static void set_scripts_dir (); - -/* IMPORTS */ -extern boolean lang_has_input_file; -extern boolean force_make_executable; -extern boolean relaxing; -extern boolean had_script; +static char *get_emulation PARAMS ((int, char **)); +static void set_scripts_dir PARAMS ((void)); /* EXPORTS */ char *default_target; -char *output_filename = "a.out"; +const char *output_filename = "a.out"; /* Name this program was invoked by. */ char *program_name; @@ -1214,6 +1209,17 @@ subfile_wanted_p (entry) (bfd_asymbol_bfd (com)->usrdata))->common_section = bfd_make_section_old_way (bfd_asymbol_bfd (com), "COMMON"); } + + /* If the symbol is not in the generic + common section, we must make sure the + BFD has a section to hang it on to. */ + if (com->section != &bfd_com_section + && (com->section->owner + != bfd_asymbol_bfd (com))) + bfd_make_section + (bfd_asymbol_bfd (com), + bfd_get_section_name (bfd_asymbol_bfd (com), + com->section)); } } ASSERT (p->udata == 0); diff --git a/ld/ldmain.h b/ld/ldmain.h index 9f3fa1a63a..7b41478431 100644 --- a/ld/ldmain.h +++ b/ld/ldmain.h @@ -1,6 +1,5 @@ /* ldmain.h - - - Copyright (C) 1991 Free Software Foundation, Inc. + Copyright 1991, 1992 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -18,6 +17,26 @@ along with GLD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -PROTO(void, Q_enter_global_ref,(asymbol **)); -PROTO(void, Q_read_file_symbols,(struct lang_input_statement_struct *)); +#ifndef LDMAIN_H +#define LDMAIN_H +extern char *program_name; +extern bfd *output_bfd; +extern char *default_target; +extern boolean trace_files; +extern boolean trace_file_tries; +extern boolean write_map; +extern int g_switch_value; +extern unsigned int commons_pending; +extern const char *output_filename; +extern char lprefix; +extern unsigned int total_files_seen; +extern unsigned int total_symbols_seen; + +extern void enter_global_ref PARAMS ((asymbol **, CONST char *)); +extern void ldmain_open_file_read_symbol + PARAMS ((struct lang_input_statement_struct *)); +extern void refize PARAMS ((ldsym_type *sp, asymbol **nlist_p)); +extern void add_ysym PARAMS ((char *)); + +#endif diff --git a/ld/ldmisc.c b/ld/ldmisc.c index 60df285d52..a3ec88b01b 100644 --- a/ld/ldmisc.c +++ b/ld/ldmisc.c @@ -26,27 +26,20 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ld.h" #include "ldmisc.h" +#include "ldexp.h" #include "ldlang.h" #include "ldlex.h" -/* IMPORTS */ - -extern char *program_name; - -extern FILE *ldlex_input_stack; -extern char *ldfile_input_filename; -extern ld_config_type config; - - -extern int errno; -extern int sys_nerr; -extern char *sys_errlist[]; +#include "ldsym.h" +#include "ldmain.h" +#include "ldfile.h" /* VARARGS*/ static void finfo (); /* + %% literal % %F error is fatal - %P print progam name + %P print program name %S print script file and linenumber %E current bfd error or errno %I filename from a lang_input_statement_type @@ -57,9 +50,9 @@ static void finfo (); %v hex bfd_vma, no leading zeros %C Clever filename:linenumber %R info about a relent - % + %s arbitrary string, like printf + %d integer, like printf */ -extern bfd *output_bfd; static char * demangle(string, remove_underscore) @@ -101,11 +94,22 @@ vfinfo(fp, fmt, arg) fmt ++; switch (*fmt++) { + default: + fprintf(fp,"%%%c", fmt[-1]); + break; + + case '%': + /* literal % */ + putc('%', fp); + break; + case 'X': + /* no object output, fail return */ config.make_executable = false; break; case 'V': + /* hex bfd_vma */ { bfd_vma value = va_arg(arg, bfd_vma); fprintf_vma(fp, value); @@ -113,6 +117,7 @@ vfinfo(fp, fmt, arg) break; case 'v': + /* hex bfd_vma, no leading zeros */ { char buf[100]; char *p = buf; @@ -127,6 +132,7 @@ vfinfo(fp, fmt, arg) break; case 'T': + /* symbol table entry */ { asymbol *symbol = va_arg(arg, asymbol *); if (symbol) @@ -151,6 +157,7 @@ vfinfo(fp, fmt, arg) break; case 'B': + /* filename from a bfd */ { bfd *abfd = va_arg(arg, bfd *); if (abfd->my_archive) { @@ -164,19 +171,22 @@ vfinfo(fp, fmt, arg) break; case 'F': + /* error is fatal */ fatal = true; break; case 'P': + /* print program name */ fprintf(fp,"%s", program_name); break; case 'E': - /* Replace with the most recent errno explanation */ + /* current bfd error or errno */ fprintf(fp, bfd_errmsg(bfd_error)); break; case 'I': + /* filename from a lang_input_statement_type */ { lang_input_statement_type *i = va_arg(arg,lang_input_statement_type *); @@ -186,9 +196,8 @@ vfinfo(fp, fmt, arg) break; case 'S': - /* Print source script file and line number */ + /* print script file and linenumber */ { - extern unsigned int lineno; if (ldfile_input_filename == (char *)NULL) { fprintf(fp,"command line"); } @@ -211,6 +220,8 @@ vfinfo(fp, fmt, arg) break; case 'C': + /* Clever filename:linenumber with function name if possible, + or section name as a last resort */ { CONST char *filename; CONST char *functionname; @@ -235,7 +246,7 @@ vfinfo(fp, fmt, arg) if (functionname != (char *)NULL) { cplus_name = demangle(functionname, 1); - fprintf(fp,"%s:%u: (%s)", filename, linenumber, cplus_name); + fprintf(fp,"%s:%u: %s", filename, linenumber, cplus_name); } else if (linenumber != 0) @@ -250,32 +261,26 @@ vfinfo(fp, fmt, arg) break; case 's': + /* arbitrary string, like printf */ fprintf(fp,"%s", va_arg(arg, char *)); break; case 'd': + /* integer, like printf */ fprintf(fp,"%d", va_arg(arg, int)); break; - - default: - fprintf(fp,"%s", va_arg(arg, char *)); - break; } } } if (fatal == true) { - extern char *output_filename; if (output_filename) { - char *new = malloc(strlen(output_filename)+2); - extern bfd *output_bfd; - - strcpy(new, output_filename); if (output_bfd && output_bfd->iostream) fclose((FILE *)(output_bfd->iostream)); - unlink(new); + if (delete_output_file_on_failure) + unlink (output_filename); } exit(1); } @@ -283,7 +288,10 @@ vfinfo(fp, fmt, arg) /* Format info message and print on stdout. */ -void info(va_alist) +/* (You would think this should be called just "info", but then you would + hosed by LynxOS, which defines that name in its libc.) */ + +void info_msg(va_alist) va_dcl { char *fmt; @@ -341,7 +349,7 @@ info_assert(file, line) char *file; unsigned int line; { - einfo("%F%P internal error %s %d\n", file,line); + einfo("%F%P: internal error %s %d\n", file,line); } /* Return a newly-allocated string @@ -377,7 +385,7 @@ ldmalloc (size) PTR result = malloc ((int)size); if (result == (char *)NULL && size != 0) - einfo("%F%P virtual memory exhausted\n"); + einfo("%F%P: virtual memory exhausted\n"); return result; } @@ -398,7 +406,7 @@ ldrealloc (ptr, size) PTR result = realloc (ptr, (int)size); if (result == (char *)NULL && size != 0) - einfo("%F%P virtual memory exhausted\n"); + einfo("%F%P: virtual memory exhausted\n"); return result; } diff --git a/ld/ldmisc.h b/ld/ldmisc.h index a9391cd0cf..e22abdbf7f 100644 --- a/ld/ldmisc.h +++ b/ld/ldmisc.h @@ -1,12 +1,11 @@ /* ldmisc.h - - - Copyright (C) 1991 Free Software Foundation, Inc. + Copyright 1991, 1992 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. GLD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) + the Free Software Foundation; either version 2, or (at your option) any later version. GLD is distributed in the hope that it will be useful, @@ -18,17 +17,32 @@ along with GLD; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#ifndef LDMISC_H +#define LDMISC_H /* VARARGS*/ -PROTO(void,info,()); -PROTO(void,info_assert,(char *, unsigned int)); -PROTO(void,yyerror,(char *)); -PROTO(char *,concat,(CONST char *, CONST char *, CONST char *)); -PROTO(char *, ldmalloc,(size_t)); -PROTO(char *,buystring,(CONST char *CONST)); +extern void einfo (); +/* VARARGS*/ +extern void minfo (); +/* VARARGS*/ +extern void info_msg (); +extern void info_assert PARAMS ((char *, unsigned int)); +extern void multiple_warn PARAMS ((char *message1, asymbol *sym, + char *message2, asymbol *sy)); +extern void yyerror PARAMS ((char *)); +extern char *concat PARAMS ((CONST char *, CONST char *, CONST char *)); +extern PTR ldmalloc PARAMS ((size_t)); +extern PTR ldrealloc PARAMS ((PTR, size_t)); +extern char *buystring PARAMS ((CONST char *CONST)); + #define ASSERT(x) \ -{ if (!(x)) info_assert(__FILE__,__LINE__); } +do { if (!(x)) info_assert(__FILE__,__LINE__); } while (0) #define FAIL() \ -{ info_assert(__FILE__,__LINE__); } +do { info_assert(__FILE__,__LINE__); } while (0) + +extern void print_space PARAMS ((void)); +extern void print_nl PARAMS ((void)); +extern void print_address PARAMS ((bfd_vma value)); + +#endif diff --git a/ld/ldsym.c b/ld/ldsym.c index a948e9ea90..6b808d757d 100644 --- a/ld/ldsym.c +++ b/ld/ldsym.c @@ -55,12 +55,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ld.h" #include "ldsym.h" #include "ldmisc.h" +#include "ldexp.h" #include "ldlang.h" -/* IMPORT */ -extern int symbol_truncate; -extern bfd *output_bfd; -extern strip_symbols_type strip_symbols; -extern discard_locals_type discard_locals; +#include "mri.h" +#include "ldmain.h" + /* Head and tail of global symbol table chronological list */ ldsym_type *symbol_head = (ldsym_type *) NULL; @@ -68,8 +67,6 @@ ldsym_type **symbol_tail_ptr = &symbol_head; CONST char *keepsyms_file; int kept_syms; -extern ld_config_type config; - struct obstack global_sym_obstack; #define obstack_chunk_alloc ldmalloc #define obstack_chunk_free free @@ -80,8 +77,6 @@ struct obstack global_sym_obstack; */ unsigned int global_symbol_count; -/* IMPORTS */ - /* LOCALS */ #define TABSIZE 1009 static ldsym_type *global_symbol_hash_table[TABSIZE]; @@ -288,6 +283,10 @@ egress: return out; } +#if 0 + +/* This function is not used. */ + static void list_file_locals (entry) lang_input_statement_type *entry; @@ -309,6 +308,7 @@ list_file_locals (entry) } } +#endif static void print_file_stuff (f) @@ -426,8 +426,6 @@ ldsym_print_symbol_table () } } -extern lang_output_section_statement_type *create_object_symbols; -extern char lprefix; static asymbol ** write_file_locals (output_buffer) asymbol **output_buffer; @@ -632,13 +630,13 @@ ldsym_write () the number of files (for the per file symbols) +1 (for the null at the end) */ - extern unsigned int total_files_seen; - extern unsigned int total_symbols_seen; - - asymbol **symbol_table = (asymbol **) - ldmalloc ((bfd_size_type) (global_symbol_count + - total_files_seen + - total_symbols_seen + 1) * sizeof (asymbol *)); + asymbol **symbol_table = + ((asymbol **) + ldmalloc ((bfd_size_type) ((global_symbol_count + + total_files_seen + + total_symbols_seen + + 1) + * sizeof (asymbol *)))); asymbol **tablep = write_file_locals (symbol_table); tablep = write_file_globals (tablep); diff --git a/ld/ldsym.h b/ld/ldsym.h index 49fcb80e9b..2efb39221e 100644 --- a/ld/ldsym.h +++ b/ld/ldsym.h @@ -61,6 +61,8 @@ typedef struct user_symbol_struct int flags; } ldsym_type; +extern ldsym_type *symbol_head; + extern CONST char *keepsyms_file; extern int kept_syms; @@ -71,7 +73,6 @@ void ldsym_write PARAMS ((void)); boolean ldsym_undefined PARAMS ((CONST char *)); #define FOR_EACH_LDSYM(x) \ - extern ldsym_type *symbol_head; \ ldsym_type *x; \ for (x = symbol_head; x != (ldsym_type *)NULL; x = x->next) diff --git a/ld/ldwrite.c b/ld/ldwrite.c index fc7759f358..c073263709 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -1,5 +1,5 @@ /* Copyright (C) 1991 Free Software Foundation, Inc. - + This file is part of GLD, the Gnu Linker. This program is free software; you can redistribute it and/or modify @@ -17,15 +17,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id$ -*/ - -/* This module writes out the final image by reading sections from the input files, relocating them and writing them out There are two main paths through this module, one for normal - operation and one for partial linking. + operation and one for partial linking. During normal operation, raw section data is read along with the associated relocation information, the relocation info applied and @@ -35,7 +31,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ out how big the output relocation vector will be. Then raw data is read, relocated and written section by section. - Written by Steve Chamberlain steve@cygnus.com + Written by Steve Chamberlain sac@cygnus.com */ @@ -43,372 +39,86 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "sysdep.h" -#include "ldlang.h" #include "ld.h" +#include "ldexp.h" +#include "ldlang.h" #include "ldwrite.h" #include "ldmisc.h" #include "ldsym.h" #include "ldgram.h" - - - - -/* Static vars for do_warnings and subroutines of it */ -int list_unresolved_refs; /* List unresolved refs */ -int list_warning_symbols; /* List warning syms */ -int list_multiple_defs; /* List multiple definitions */ -extern int errno; -extern char *sys_errlist[]; - -extern unsigned int undefined_global_sym_count; - -extern bfd *output_bfd; - -extern struct lang_output_section_statement_struct * create_object_symbols; - -extern char lprefix; - -#ifdef __STDC__ -void lang_for_each_statement(void (*func)()); -#else /* __STDC__ */ -void lang_for_each_statement(); -#endif /* __STDC__ */ - -extern bfd_size_type largest_section; -ld_config_type config; - -extern unsigned int global_symbol_count; - -boolean trace_files; - -static void -DEFUN(perform_relocation,(input_bfd, - input_section, - data, - symbols), - bfd *input_bfd AND - asection *input_section AND - PTR data AND - asymbol **symbols) -{ - static asymbol *error_symbol = (asymbol *)NULL; - static unsigned int error_count = 0; -#define MAX_ERRORS_IN_A_ROW 5 - bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, input_section); - - arelent **reloc_vector = (arelent **)ldmalloc(reloc_size); - arelent **parent; - bfd *ob = output_bfd; - asection *os = input_section->output_section; - if (config.relocateable_output == false) ob = (bfd *)NULL; - - input_section->_cooked_size = input_section->_raw_size; - input_section->reloc_done = 1; - - if (bfd_canonicalize_reloc(input_bfd, - input_section, - reloc_vector, - symbols) ) - { - for (parent = reloc_vector; *parent; parent++) - { - - bfd_reloc_status_type r= - bfd_perform_relocation(input_bfd, - *parent, - data, - input_section, - ob); - - if (r == bfd_reloc_ok) { - if (ob != (bfd *)NULL) { - /* A parital link, so keep the relocs */ - - /* Add to each relocation the offset of where it lives - in the output section */ -/* (*parent)->address += input_section->output_offset;*/ - - os->orelocation[os->reloc_count] = *parent; - os->reloc_count++; - } - } - else - { - asymbol *s; - arelent *p = *parent; - - if (ob != (bfd *)NULL) { - /* A parital link, so keep the relocs */ - os->orelocation[os->reloc_count] = *parent; - os->reloc_count++; - } - - if (p->sym_ptr_ptr != (asymbol **)NULL) { - s = *(p->sym_ptr_ptr); - } - else { - s = (asymbol *)NULL; - } - switch (r) - { - case bfd_reloc_undefined: - /* We remember the symbol, and never print more than - a reasonable number of them in a row */ - if (s == error_symbol) { - error_count++; - } - else { - error_count = 0; - error_symbol = s; - } - if (error_count < MAX_ERRORS_IN_A_ROW) { - einfo("%C: undefined reference to `%T'\n", - input_bfd, input_section, symbols, - (*parent)->address, s); - config.make_executable = false; - } - else if (error_count == MAX_ERRORS_IN_A_ROW) { - einfo("%C: more undefined references to `%T' follow\n", - input_bfd, input_section, - symbols, (*parent)->address, s); - } - else { - /* Don't print any more */ - } - break; - case bfd_reloc_dangerous: - einfo("%B: relocation may be wrong `%T'\n", - input_bfd, s); - break; - case bfd_reloc_outofrange: - einfo("%B:%s relocation address out of range %T (%V)\n", - input_bfd, input_section->name, s, p->address); - break; - case bfd_reloc_overflow: - einfo("%B:%s relocation overflow in %T reloc type %d\n", - input_bfd, input_section->name, s, p->howto->type); - break; - default: - einfo("%F%B: relocation error, symbol `%T'\n", - input_bfd, s); - break; - } - } - } - } - free((char *)reloc_vector); -} - - - - - - -PTR data_area; +#include "ldmain.h" +#include "relax.h" static void -DEFUN(copy_and_relocate,(statement), - lang_statement_union_type *statement) -{ - switch (statement->header.type) { - case lang_fill_statement_enum: - { -#if 0 - bfd_byte play_area[SHORT_SIZE]; - unsigned int i; - bfd_putshort(output_bfd, statement->fill_statement.fill, play_area); - /* Write out all entire shorts */ - for (i = 0; - i < statement->fill_statement.size - SHORT_SIZE + 1; - i+= SHORT_SIZE) - { - bfd_set_section_contents(output_bfd, - statement->fill_statement.output_section, - play_area, - statement->data_statement.output_offset +i, - SHORT_SIZE); - - } - - /* Now write any remaining byte */ - if (i < statement->fill_statement.size) - { - bfd_set_section_contents(output_bfd, - statement->fill_statement.output_section, - play_area, - statement->data_statement.output_offset +i, - 1); - - } -#endif - } - break; - case lang_data_statement_enum: - { - bfd_vma value = statement->data_statement.value; - bfd_byte play_area[LONG_SIZE]; - unsigned int size = 0; - switch (statement->data_statement.type) { - case LONG: - bfd_put_32(output_bfd, value, play_area); - size = LONG_SIZE; - break; - case SHORT: - bfd_put_16(output_bfd, value, play_area); - size = SHORT_SIZE; - break; - case BYTE: - bfd_put_8(output_bfd, value, play_area); - size = BYTE_SIZE; - break; - } - - bfd_set_section_contents(output_bfd, - statement->data_statement.output_section, - play_area, - statement->data_statement.output_vma, - size); - - - - - } - break; - case lang_input_section_enum: - { - - asection *i = statement->input_section.section; - asection *output_section = i->output_section; - lang_input_statement_type *ifile = - statement->input_section.ifile; - if (ifile->just_syms_flag == false) { - bfd *inbfd = ifile->the_bfd; - - if (output_section->flags & SEC_LOAD && - output_section->flags & SEC_ALLOC - && bfd_get_section_size_before_reloc(i) != 0) - { - if(bfd_get_section_contents(inbfd, - i, - data_area, - (file_ptr)0, - bfd_get_section_size_before_reloc(i)) == false) - { - einfo("%F%B error reading section contents %E\n", inbfd); - } - /* Set the reloc bit */ - perform_relocation (inbfd, i, data_area, ifile->asymbols); - - - if(bfd_set_section_contents(output_bfd, - output_section, - data_area, - (file_ptr)i->output_offset, - bfd_get_section_size_after_reloc(i)) == false) - { - einfo("%F%B error writing section contents of %E\n", - output_bfd); - } - - } - } - - } - break; - - default: - /* All the other ones fall through */ - ; - - } -} - -void -DEFUN_VOID(write_norel) -{ - /* Output the text and data segments, relocating as we go. */ - lang_for_each_statement(copy_and_relocate); -} - - -static void -DEFUN(read_relocs,(abfd, section, symbols), - bfd *abfd AND - asection *section AND - asymbol **symbols) +read_relocs (abfd, section, symbols) + bfd * abfd; + asection * section; + asymbol ** symbols; { /* Work out the output section ascociated with this input section */ asection *output_section = section->output_section; - bfd_size_type reloc_size = bfd_get_reloc_upper_bound(abfd, section); - arelent **reloc_vector = (arelent **)ldmalloc(reloc_size); + bfd_size_type reloc_size = bfd_get_reloc_upper_bound (abfd, section); + arelent **reloc_vector = (arelent **) ldmalloc (reloc_size); - if (bfd_canonicalize_reloc(abfd, - section, - reloc_vector, - symbols)) { - output_section->reloc_count += section->reloc_count; - } + if (bfd_canonicalize_reloc (abfd, + section, + reloc_vector, + symbols)) + { + output_section->reloc_count += section->reloc_count; + } } -static void -DEFUN_VOID(write_rel) +static void +setup_rel () { /* - Run through each section of each file and work work out the total - number of relocation records which will finally be in each output - section - */ + Run through each section of each file and work work out the total + number of relocation records which will finally be in each output + section + */ LANG_FOR_EACH_INPUT_SECTION - (statement, abfd, section, - (read_relocs(abfd, section, statement->asymbols))); + (statement, abfd, section, + (read_relocs (abfd, section, statement->asymbols))); /* - Now run though all the output sections and allocate the space for - all the relocations - */ + Now run though all the output sections and allocate the space for + all the relocations + */ LANG_FOR_EACH_OUTPUT_SECTION - (section, + (section, (section->orelocation = - (arelent **)ldmalloc((bfd_size_type)(sizeof(arelent **)* - section->reloc_count)), - section->reloc_count = 0, - section->flags |= SEC_HAS_CONTENTS)); - - - /* - Copy the data, relocating as we go - */ - lang_for_each_statement(copy_and_relocate); + (arelent **) ldmalloc ((bfd_size_type) (sizeof (arelent **) * + section->reloc_count)), + section->reloc_count = 0)); } void -DEFUN_VOID(ldwrite) +ldwrite () { - data_area = (PTR) ldmalloc(largest_section); - if (config.relocateable_output == true) - { - write_rel(); - } - else - { - write_relaxnorel(output_bfd); - } - free(data_area); - /* Output the symbol table (both globals and locals). */ - - /* Print a map, if requested. */ - - if (config.map_file) { - ldsym_print_symbol_table (); - lang_map(); - } + PTR data_area = (PTR) ldmalloc (largest_section); ldsym_write (); + if (config.relocateable_output == true) + setup_rel (); + + write_relax (output_bfd, data_area, config.relocateable_output); + + free (data_area); + + /* Output the symbol table (both globals and locals). */ + + /* Print a map, if requested and possible. */ + + if (config.map_file) + { + ldsym_print_symbol_table (); + lang_map (); + } } - diff --git a/ld/mri.c b/ld/mri.c index 03ef2602f7..9110cb0722 100644 --- a/ld/mri.c +++ b/ld/mri.c @@ -28,10 +28,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "sysdep.h" #include "ld.h" +#include "ldexp.h" #include "ldlang.h" +#include "ldmisc.h" #include "mri.h" #include "ldgram.h" -#include "ldexp.h" struct section_name_struct { @@ -117,8 +118,6 @@ mri_only_load (name) } -etree_type *base; - void mri_base (exp) etree_type *exp; @@ -242,10 +241,10 @@ mri_draw_tree () if (base == 0) { base = p->vma ? p->vma :exp_nameop(NAME, "."); } - lang_enter_output_section_statement(p->name, base, - p->ok_to_load ? 0 : - SEC_NEVER_LOAD, 1, - align, subalign); + lang_enter_output_section_statement (p->name, base, + p->ok_to_load ? 0 : SEC_NEVER_LOAD, + 1, align, subalign, + (etree_type *) NULL); base = 0; lang_add_wild(p->name, (char *)NULL); /* If there is an alias for this section, add it too */ @@ -306,7 +305,7 @@ void mri_name (name) CONST char *name; { - lang_add_output(name); + lang_add_output(name, 1); } @@ -317,15 +316,15 @@ mri_format (name) { if (strcmp(name, "S") == 0) { - lang_add_output_format("srec"); + lang_add_output_format("srec", 1); } else if (strcmp(name, "IEEE") == 0) { - lang_add_output_format("ieee"); + lang_add_output_format("ieee", 1); } else if (strcmp(name, "COFF") == 0) { - lang_add_output_format("coff-m68k"); + lang_add_output_format("coff-m68k", 1); } else { einfo("%P%F: unknown format type %s\n", name); diff --git a/ld/mri.h b/ld/mri.h new file mode 100644 index 0000000000..3c911e5f8c --- /dev/null +++ b/ld/mri.h @@ -0,0 +1,38 @@ +/* mri.h -- header file for MRI scripting functions + Copyright 1993 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef MRI_H +#define MRI_H + +extern int symbol_truncate; + +extern void mri_output_section PARAMS ((const char *name, etree_type *vma)); +extern void mri_only_load PARAMS ((const char *name)); +extern void mri_base PARAMS ((etree_type *exp)); +extern void mri_load PARAMS ((const char *name)); +extern void mri_order PARAMS ((const char *name)); +extern void mri_alias PARAMS ((const char *want, const char *is, int isn)); +extern void mri_name PARAMS ((const char *name)); +extern void mri_format PARAMS ((const char *name)); +extern void mri_public PARAMS ((const char *name, etree_type *exp)); +extern void mri_align PARAMS ((const char *name, etree_type *exp)); +extern void mri_alignmod PARAMS ((const char *name, etree_type *exp)); +extern void mri_truncate PARAMS ((int exp)); + +#endif diff --git a/ld/relax.c b/ld/relax.c index eb3f6e079c..9aced76c96 100644 --- a/ld/relax.c +++ b/ld/relax.c @@ -31,8 +31,9 @@ Tie together all the interseting blocks #include "coff/internal.h" #include "sysdep.h" -#include "ldlang.h" #include "ld.h" +#include "ldexp.h" +#include "ldlang.h" #include "ldwrite.h" #include "ldmisc.h" #include "ldsym.h" @@ -200,7 +201,6 @@ boolean relax_section (this_ptr) lang_statement_union_type ** this_ptr; { - extern lang_input_statement_type *script_file; lang_input_section_type *is = &((*this_ptr)->input_section); asection *i = is->section; if (!(i->owner->flags & BFD_IS_RELAXABLE))