From: Steve Chamberlain Date: Sun, 14 Apr 1991 03:22:42 +0000 (+0000) Subject: checkpoint before a merge X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1418c83b393c2a5d08cc56b306272aab660fbd9d;p=binutils-gdb.git checkpoint before a merge --- diff --git a/ld/config.h b/ld/config.h index ca4cc87745c..d5fab1b2fdd 100644 --- a/ld/config.h +++ b/ld/config.h @@ -22,6 +22,7 @@ #define EMULATION_ENVIRON "LDEMULATION" /* If in there look for the strings: */ #define GLD_EMULATION_NAME "gld" +#define VANILLA_EMULATION_NAME "vanilla" #define GLD68K_EMULATION_NAME "gld68k" #define GLD960_EMULATION_NAME "gld960" #define LNK960_EMULATION_NAME "lnk960" @@ -36,6 +37,7 @@ #define GLD68K_TARGET "a.out-generic-big" #define LNK960_TARGET "coff-Intel-big" #define GLD960_TARGET "b.out.big" +#define VANILLA_TARGET "a.out-generic-big" diff --git a/ld/ld-emul.c b/ld/ld-emul.c index 80f13290622..70ee76f5efe 100755 --- a/ld/ld-emul.c +++ b/ld/ld-emul.c @@ -36,6 +36,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ extern ld_emulation_xfer_type ld_lnk960_emulation; extern ld_emulation_xfer_type ld_gld_emulation; +extern ld_emulation_xfer_type ld_vanilla_emulation; extern ld_emulation_xfer_type ld_gld68k_emulation; extern ld_emulation_xfer_type ld_gld960_emulation; @@ -112,6 +113,9 @@ char *target; else if (strcmp(target,GLD_EMULATION_NAME)==0) { ld_emulation = &ld_gld_emulation; } + else if (strcmp(target,VANILLA_EMULATION_NAME)==0) { + ld_emulation = &ld_vanilla_emulation; + } else if (strcmp(target,GLD68K_EMULATION_NAME)==0) { ld_emulation = &ld_gld68k_emulation; } diff --git a/ld/ld-gld.c b/ld/ld-gld.c index 00d44936e85..7607462a23c 100755 --- a/ld/ld-gld.c +++ b/ld/ld-gld.c @@ -19,39 +19,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * $Id$ * - * $Log$ - * Revision 1.2 1991/03/22 23:02:29 steve - * Brought up to sync with Intel again. - * - * Revision 1.2 1991/03/15 18:45:55 rich - * foo - * - * Revision 1.1 1991/03/13 00:48:11 chrisb - * Initial revision - * - * Revision 1.7 1991/03/10 09:31:18 rich - * Modified Files: - * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c - * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h - * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c - * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c - * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h - * - * As of this round of changes, ld now builds on all hosts of (Intel960) - * interest and copy passes my copy test on big endian hosts again. - * - * Revision 1.6 1991/03/09 03:23:12 sac - * Added -Ur loader script. - * - * Revision 1.5 1991/03/06 21:59:29 sac - * Completed G++ support - * - * Revision 1.4 1991/03/06 02:23:34 sac - * Added support for partial linking. - * - * Revision 1.3 1991/02/22 17:14:56 sac - * Added RCS keywords and copyrights - * */ /* @@ -140,95 +107,17 @@ char *ignore; info("%S HLL ignored\n"); } -static char *gld_script = " \ -SEARCH_DIR(/lib) \ -SEARCH_DIR(/usr/lib) \ -SEARCH_DIR(/usr/local/lib) \ -__DYNAMIC = 0; \ -SECTIONS \ -{ \ - .text 0x2020 BLOCK(0x2000): \ - { \ - CREATE_OBJECT_SYMBOLS \ - *(.text) \ - _etext = ALIGN( 0x2000); \ - } \ - .data ALIGN(0x2000) : \ - { \ - *(.data) \ - ___DTOR_LIST__=. ; \ - LONG((___CTOR_LIST__ - .)/4 -2) \ - *(___DTOR_LIST__) \ - LONG(0) \ - ___CTOR_LIST__=. ; \ - LONG((_edata - .)/4 -2) \ - *(___CTOR_LIST__) \ - LONG(0) \ - _edata = .; \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - *(.bss) \ - [COMMON] \ - _end=.; \ - } \ -}"; - - -static char *gld_script_option_Ur = "\ -SEARCH_DIR(/lib) \ -SEARCH_DIR(/usr/lib) \ -SEARCH_DIR(/usr/local/lib) \ -SECTIONS \ -{ \ - .text 0: \ - { \ - CREATE_OBJECT_SYMBOLS \ - *(.text) \ - } \ - .data SIZEOF(.text) + ADDR(.text) : \ - { \ - *(.data) \ - ___DTOR_LIST__=. ; \ - LONG((___CTOR_LIST__ - .)/4 -2) \ - *(___DTOR_LIST__) \ - LONG(0) \ - ___CTOR_LIST__=. ; \ - LONG((___end_list__ - .)/4 -2) \ - *(___CTOR_LIST__) \ - LONG(0) \ - ___end_list__ = . ; \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - *(.bss) \ - [COMMON] \ - } \ -} \ -"; - -static char *gld_script_option_r = "\ -SEARCH_DIR(/lib) \ -SEARCH_DIR(/usr/lib) \ -SEARCH_DIR(/usr/local/lib) \ -SECTIONS \ -{ \ - .text 0: \ - { \ - CREATE_OBJECT_SYMBOLS \ - *(.text) \ - } \ - .data SIZEOF(.text) + ADDR(.text) : \ - { \ - *(.data) \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - *(.bss) \ - [COMMON] \ - } \ -} \ -"; +static char *gld_script = +#include "ld-gld.x" +; + +static char *gld_script_option_Ur = +#include "ld-gld-Ur.x" +; + +static char *gld_script_option_r = +#include "ld-gld-r.x" +; static char *gld_get_script() { diff --git a/ld/ld-gld68k.c b/ld/ld-gld68k.c index 004594b27f2..5d996e3236b 100755 --- a/ld/ld-gld68k.c +++ b/ld/ld-gld68k.c @@ -105,96 +105,16 @@ char *ignore; info("%S HLL ignored\n"); } -static char *gld68k_script = " \ -SEARCH_DIR(/lib) \ -SEARCH_DIR(/usr/lib) \ -SEARCH_DIR(/usr/local/lib) \ -__DYNAMIC = 0; \ -SECTIONS \ -{ \ - .text 0x2020 BLOCK(0x2000): \ - { \ - CREATE_OBJECT_SYMBOLS \ - *(.text) \ - _etext = ALIGN( 0x2000); \ - } \ - .data ALIGN(0x20000) : \ - { \ - *(.data) \ - ___DTOR_LIST__=. ; \ - LONG((___CTOR_LIST__ - .)/4 -2) \ - *(___DTOR_LIST__) \ - LONG(0) \ - ___CTOR_LIST__=. ; \ - LONG((_edata - .)/4 -2) \ - *(___CTOR_LIST__) \ - LONG(0) \ - _edata = .; \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - *(.bss) \ - [COMMON] \ - _end=.; \ - } \ -}"; - - -static char *gld68k_script_option_Ur = "\ -SEARCH_DIR(/lib) \ -SEARCH_DIR(/usr/lib) \ -SEARCH_DIR(/usr/local/lib) \ -SECTIONS \ -{ \ - .text 0: \ - { \ - CREATE_OBJECT_SYMBOLS \ - *(.text) \ - } \ - .data SIZEOF(.text) + ADDR(.text) : \ - { \ - *(.data) \ - ___DTOR_LIST__=. ; \ - LONG((___CTOR_LIST__ - .)/4 -2) \ - *(___DTOR_LIST__) \ - LONG(0) \ - ___CTOR_LIST__=. ; \ - LONG((___end_list__ - .)/4 -2) \ - *(___CTOR_LIST__) \ - LONG(0) \ - ___end_list__ = . ; \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - *(.bss) \ - [COMMON] \ - } \ -} \ -"; - -static char *gld68k_script_option_r = "\ -SEARCH_DIR(/lib) \ -SEARCH_DIR(/usr/lib) \ -SEARCH_DIR(/usr/local/lib) \ -SECTIONS \ -{ \ - .text 0: \ - { \ - CREATE_OBJECT_SYMBOLS \ - *(.text) \ - } \ - .data SIZEOF(.text) + ADDR(.text) : \ - { \ - *(.data) \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - *(.bss) \ - [COMMON] \ - } \ -} \ -"; - +static char *gld68k_script = +#include "ld-gld68k.x" +; + +static char *gld68k_script_option_Ur = +#include "ld-gld68k-Ur.x" +; +static char *gld68k_script_option_r = +#include "ld-gld68k-r.x" +; static char *gld68k_get_script() { extern ld_config_type config; diff --git a/ld/ld-gld960.c b/ld/ld-gld960.c index 0577fa470a4..fb903102853 100755 --- a/ld/ld-gld960.c +++ b/ld/ld-gld960.c @@ -20,9 +20,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ $Id$ $Log$ - Revision 1.2 1991/03/22 23:02:30 steve - Brought up to sync with Intel again. + Revision 1.3 1991/04/14 03:22:11 steve + checkpoint before a merge + * Revision 1.2 1991/03/22 23:02:30 steve + * Brought up to sync with Intel again. + * * Revision 1.3 1991/03/16 22:27:24 rich * fish * @@ -143,31 +146,10 @@ gld960_hll() } -static char *script = "\ - \ -SECTIONS \ -{ \ - .text : \ - { \ - CREATE_OBJECT_SYMBOLS \ - *(.text) \ - _etext =.;\ - } \ - \ - .data SIZEOF(.text) + ADDR(.text):\ - { \ - \ - *(.data) \ - _edata = .; \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { _bss_start = .;\ - *(.bss) \ - [COMMON] \ - _end = . ; \ - } \ -} \ -"; +static char *script = +#include "ld-gld960.x" +; + static char * gld960_get_script() diff --git a/ld/ld-lnk960.c b/ld/ld-lnk960.c index 0d9a1fc8e80..d099d960bfe 100755 --- a/ld/ld-lnk960.c +++ b/ld/ld-lnk960.c @@ -18,40 +18,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id$ - - $Log$ - Revision 1.3 1991/04/08 23:21:26 steve - *** empty log message *** - - * Revision 1.2 1991/03/22 23:02:31 steve - * Brought up to sync with Intel again. - * - * Revision 1.2 1991/03/15 18:45:55 rich - * foo - * - * Revision 1.1 1991/03/13 00:48:13 chrisb - * Initial revision - * - * Revision 1.6 1991/03/10 09:31:20 rich - * Modified Files: - * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c - * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h - * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c - * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c - * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h - * - * As of this round of changes, ld now builds on all hosts of (Intel960) - * interest and copy passes my copy test on big endian hosts again. - * - * Revision 1.5 1991/03/09 03:23:47 sac - * Now looks in G960BASE if I960BASE isn't defined. - * - * Revision 1.4 1991/03/06 02:23:35 sac - * Added support for partial linking. - * - * Revision 1.3 1991/02/22 17:14:58 sac - * Added RCS keywords and copyrights - * */ /* @@ -131,6 +97,33 @@ char *name; +#ifdef GNU960 + +static void +lnk960_before_parse() +{ + static char *env_variables[] = { "G960LIB", "G960BASE", 0 }; + char **p; + char *env ; + + for ( p = env_variables; *p; p++ ){ + env = (char *) getenv(*p); + if (env) { + ldfile_add_library_path(concat(env,"/lib/libcoff","")); + } + } + + env= (char *) getenv("I960BASE"); + if ( env ) { + ldfile_add_library_path(concat(env,"/lib","")); + } + + ldfile_output_architecture = bfd_arch_i960; + ldfile_output_machine = bfd_mach_i960_core; +} + +#else /* not GNU960 */ + static void lnk960_before_parse() { @@ -149,6 +142,9 @@ lnk960_before_parse() ldfile_output_machine = bfd_mach_i960_core; } +#endif /* GNU960 */ + + static void add_on(list, search) lib_list_type *list; @@ -166,7 +162,7 @@ static void lnk960_after_parse() /* If there has been no arch, default to -KB */ if (ldfile_output_machine_name[0] ==0) { - ldfile_add_arch("kb"); + ldfile_add_arch("KB"); } /* if there has been no hll list then add our own */ @@ -211,6 +207,7 @@ lnk960_after_allocation() } } + static struct { unsigned long number; @@ -255,64 +252,37 @@ lnk960_set_output_arch() static char * lnk960_choose_target() { +#ifdef GNU960 + + return bfd_make_targ_name(BFD_COFF_FORMAT,HOST_BYTE_ORDER_BIG_P); + +#else + char *from_outside = getenv(TARGET_ENVIRON); if (from_outside != (char *)NULL) return from_outside; return LNK960_TARGET; + +#endif } /* The default script if none is offered */ -static char *lnk960_script = "\ -SECTIONS \ -{ \ - .text : \ - { \ - *(.text) \ - } \ -_etext = .;\ - .data SIZEOF(.text) + ADDR(.text):\ - { \ - *(.data) \ - } \ -_edata = .; \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - _bss_start = . ;\ - *(.bss) \ - [COMMON] \ - } \ -_end = . ; \ -} \ -"; - -static char *lnk960_script_relocateable = "\ -SECTIONS \ -{ \ - .text 0x40000000: \ - { \ - *(.text) \ - } \ - .data 0:\ - { \ - *(.data) \ - } \ - .bss SIZEOF(.data) + ADDR(.data) : \ - { \ - *(.bss) \ - [COMMON] \ - } \ -} \ -"; +static char *lnk960_script = +#include "ld-lnk960.x" +; -static char *lnk960_get_script() -{ -extern ld_config_type config; -if (config.relocateable_output) { - return lnk960_script_relocateable; -} -return lnk960_script; +static char *lnk960_script_relocateable = +#include "ld-lnk960-r.x" +; +static char *lnk960_get_script() +{ + extern ld_config_type config; + if (config.relocateable_output) { + return lnk960_script_relocateable; + } + return lnk960_script; } struct ld_emulation_xfer_struct ld_lnk960_emulation = { diff --git a/ld/ld.h b/ld/ld.h index fb2b62a908b..7c87024ab15 100644 --- a/ld/ld.h +++ b/ld/ld.h @@ -42,20 +42,6 @@ typedef struct user_section_struct { #define get_userdata(x) ((x)->userdata) #define as_output_section_statement(x) ((x)->otheruserdata) -#if 0 -/* - * Structure for communication between do_file_warnings and it's - * helper routines. Will in practice be an array of three of these: - * 0) Current line, 1) Next line, 2) Source file info. - */ -struct line_debug_entry -{ - int line; - char *filename; - struct nlist *sym; -}; - -#endif /* Which symbols should be stripped (omitted from the output): @@ -76,19 +62,8 @@ enum { DISCARD_NONE, DISCARD_ALL, DISCARD_L } discard_locals; #define ALIGN(this, boundary) ((( (this) + ((boundary) -1)) & (~((boundary)-1)))) -#if 0 -#define FOREACHGLOBALSYMBOL(x) ldsym_type *x; for (x = symbol_head; x; x=x->next) - - - -#define SECTIONLOOP(abfd, ptr) \ - asection *ptr; for(ptr = abfd->sections; ptr;ptr=ptr->next) - - -#endif typedef struct { - /* 1 => assign space to common symbols even if `relocatable_output'. */ boolean force_common_definition; @@ -112,10 +87,10 @@ typedef struct } ld_config_type; -#define set_asymbol_chain(x,y) ((x)->udata = (void *)y) +#define set_asymbol_chain(x,y) ((x)->udata = (PTR)y) #define get_asymbol_chain(x) ((asymbol **)((x)->udata)) #define get_loader_symbol(x) ((loader_global_asymbol *)((x)->udata)) -#define set_loader_symbol(x,y) ((x)->udata = (void *)y) +#define set_loader_symbol(x,y) ((x)->udata = (PTR)y) diff --git a/ld/ldexp.c b/ld/ldexp.c index 5b8581f0aef..583b9bcc9d8 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -18,34 +18,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id$ - - $Log$ - Revision 1.1 1991/03/21 21:28:34 gumby - Initial revision - - * Revision 1.1 1991/03/13 00:48:16 chrisb - * Initial revision - * - * Revision 1.6 1991/03/10 09:31:22 rich - * Modified Files: - * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c - * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h - * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c - * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c - * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h - * - * As of this round of changes, ld now builds on all hosts of (Intel960) - * interest and copy passes my copy test on big endian hosts again. - * - * Revision 1.5 1991/03/09 03:25:04 sac - * Added support for LONG, SHORT and BYTE keywords in scripts - * - * Revision 1.4 1991/03/06 02:27:15 sac - * Added LONG, SHORT and BYTE keywords - * - * Revision 1.3 1991/02/22 17:14:59 sac - * Added RCS keywords and copyrights - * */ /* @@ -519,7 +491,7 @@ bfd_vma *dotp; } - def->udata = (void *)NULL; + def->udata = (PTR)NULL; def->name = sy->name; Q_enter_global_ref(def_ptr); } diff --git a/ld/ldfile.c b/ld/ldfile.c index bc55f04b835..f996b934318 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -19,31 +19,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id$ - - $Log$ - Revision 1.1 1991/03/21 21:28:37 gumby - Initial revision - - * Revision 1.2 1991/03/15 18:45:55 rich - * foo - * - * Revision 1.1 1991/03/13 00:48:18 chrisb - * Initial revision - * - * Revision 1.4 1991/03/10 09:31:24 rich - * Modified Files: - * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c - * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h - * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c - * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c - * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h - * - * As of this round of changes, ld now builds on all hosts of (Intel960) - * interest and copy passes my copy test on big endian hosts again. - * - * Revision 1.3 1991/02/22 17:15:00 sac - * Added RCS keywords and copyrights - * */ /* @@ -60,11 +35,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ldlang.h" #include "ldfile.h" -#include - /* EXPORT */ char *ldfile_input_filename; -char *ldfile_output_machine_name; +CONST char * ldfile_output_machine_name; unsigned long ldfile_output_machine; enum bfd_architecture ldfile_output_architecture; boolean had_script; @@ -96,6 +69,8 @@ typedef struct search_arch_struct static search_arch_type *search_arch_head; static search_arch_type **search_arch_tail_ptr = &search_arch_head; + + void ldfile_add_library_path(name) char *name; @@ -115,8 +90,9 @@ char *attempt; lang_input_statement_type *entry; { entry->the_bfd = bfd_openr(attempt, entry->target); - - + if (option_v == true && entry->the_bfd == (bfd *)NULL) { + info("attempt to open %s failed\n", attempt); + } return entry->the_bfd; } @@ -143,11 +119,11 @@ char *suffix; entry->filename, arch, suffix); } else { - if (entry->filename[0] == '/') { - strcpy(buffer, entry->filename); - } else { - sprintf(buffer,"%s/%s",search->name, entry->filename); - } /* */ + if (entry->filename[0] == '/' || entry->filename[0] == '.') { + strcpy(buffer, entry->filename); + } else { + sprintf(buffer,"%s/%s",search->name, entry->filename); + } } string = buystring(buffer); desc = cached_bfd_openr (string, entry); @@ -178,6 +154,8 @@ lang_input_statement_type *entry; if (entry->search_dirs_flag) { search_arch_type *arch; + /* Try to open or lib.a */ + for (arch = search_arch_head; arch != (search_arch_type *)NULL; arch = arch->next) { @@ -213,14 +191,21 @@ char *exten; FILE *result; char buff[1000]; result = fopen(name, "r"); - if (result && option_v == true) { + if (option_v == true) { + if (result == (FILE *)NULL) { + info("can't find "); + } info("%s\n",name); + return result; } sprintf(buff, "%s%s", name, exten); result = fopen(buff, "r"); - if (result && option_v == true) { + if (option_v == true) { + if (result == (FILE *)NULL) { + info("can't find "); + } info("%s\n", buff); } return result; @@ -265,12 +250,14 @@ char *name; void -ldfile_add_arch(name) -char *name; +DEFUN(ldfile_add_arch,(in_name), + CONST char *CONST in_name) { + char *name = buystring(in_name); search_arch_type *new = (search_arch_type *)ldmalloc(sizeof(search_arch_type)); - ldfile_output_machine_name = name; + + ldfile_output_machine_name = in_name; new->name = name; new->next = (search_arch_type*)NULL; diff --git a/ld/ldfile.h b/ld/ldfile.h index 876d47f6db9..f4ad289aa5f 100644 --- a/ld/ldfile.h +++ b/ld/ldfile.h @@ -20,7 +20,7 @@ -PROTO(void,ldfile_add_arch,(char *)); +PROTO(void,ldfile_add_arch,(CONST char *CONST)); PROTO(void,ldfile_add_library_path,(char *)); PROTO(void,ldfile_open_command_file,(char *name)); PROTO(void,ldfile_open_file,(struct lang_input_statement_struct *)); diff --git a/ld/ldgram.y b/ld/ldgram.y index 2b1ae7715c1..c9af2490891 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -1,4 +1,4 @@ - +%{ /* * $Id$ * @@ -59,10 +59,8 @@ char *current_file; boolean ldgram_want_filename = true; boolean had_script = false; boolean force_make_executable = false; -boolean ldgram_has_inputfile = false; - boolean ldgram_in_expression = false; - +boolean ldgram_in_script = false; boolean ldgram_in_defsym = false; /* LOCALS */ @@ -114,16 +112,16 @@ boolean ldgram_in_defsym = false; %token SECTIONS %token '{' '}' %token ALIGNMENT SIZEOF_HEADERS -%token NEXT SIZEOF ADDR +%token NEXT SIZEOF ADDR SCRIPT ENDSCRIPT %token MEMORY %token DSECT NOLOAD COPY INFO OVERLAY %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S -%token OPTION_format OPTION_F +%token OPTION_format OPTION_F OPTION_u %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X %token OPTION_v OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT OPTION_defsym -%token OPTION_n OPTION_r OPTION_o OPTION_b OPTION_A +%token OPTION_n OPTION_r OPTION_o OPTION_b OPTION_A OPTION_R %token OPTION_l OPTION_L OPTION_T OPTION_Aarch OPTION_Tfile OPTION_Texp %token OPTION_Ur %token ORIGIN FILL OPTION_g @@ -152,7 +150,8 @@ command_line: ; command_line_option: - OPTION_v + SCRIPT ifile_list ENDSCRIPT + | OPTION_v { ldversion(); option_v = true; @@ -173,7 +172,10 @@ command_line_option: | OPTION_S { strip_symbols = STRIP_DEBUGGER; } - + | OPTION_u NAME { + ldlang_add_undef($2); + } + | OPTION_r { config.relocateable_output = true; config.build_constructors = false; @@ -202,10 +204,10 @@ command_line_option: { force_make_executable = true; } - | OPTION_d { + | OPTION_d { command_line.force_common_definition = true; } - | OPTION_dc + | OPTION_dc { command_line.force_common_definition = true; } @@ -213,23 +215,28 @@ command_line_option: { /* Ignored */ } - | OPTION_dp + | OPTION_dp { command_line.force_common_definition = true; } - | OPTION_format NAME + | OPTION_format NAME { lang_add_target($2); } - | OPTION_Texp - { hex_mode =true; } - exp - { lang_section_start($1, $3); - hex_mode = false; } + { + hex_mode =true; + } + INT + { + lang_section_start($1,exp_intop($3)); + hex_mode = false; + } | OPTION_Aarch - { ldfile_add_arch($1); } + { + ldfile_add_arch($1); + } | OPTION_b NAME { lang_add_target($2); @@ -237,21 +244,21 @@ command_line_option: | OPTION_L { ldfile_add_library_path($1); - } + } | OPTION_F { /* Ignore */ } - - | ifile_p1 - | input_list - | OPTION_c filename + | NAME + { lang_add_input_file($1,lang_input_file_is_file_enum, + (char *)NULL); } + | OPTION_c filename script_file { ldfile_open_command_file($2); } - | OPTION_Tfile - { ldfile_open_command_file($1); } + | OPTION_Tfile + { ldfile_open_command_file($1); } script_file - | OPTION_T filename - { ldfile_open_command_file($2); } + | OPTION_T filename + { ldfile_open_command_file($2); } script_file | OPTION_l { @@ -259,7 +266,7 @@ command_line_option: lang_input_file_is_l_enum, (char *)NULL); } - | OPTION_A filename + | OPTION_R filename { lang_add_input_file($2, lang_input_file_is_symbols_only_enum, @@ -268,47 +275,38 @@ command_line_option: | OPTION_defsym { ldgram_in_defsym = true; + ldgram_in_expression = true; hex_mode = true; } assignment { hex_mode = false; ldgram_in_defsym = false; + ldgram_in_expression = false; } + | '-' NAME + { info("%P%F Unrecognised option -%s\n", $2); } ; -input_section_spec: - NAME - { - lang_add_wild((char *)NULL, $1); - } - | '[' - { - current_file = (char *)NULL; - } - file_NAME_list - ']' - | NAME - { - current_file =$1; - } - '(' file_NAME_list ')' - | '*' - { - current_file = (char *)NULL; - } - '(' file_NAME_list ')' - ; + -file_NAME_list: - NAME - { lang_add_wild($1, current_file); } - | file_NAME_list opt_comma NAME - { lang_add_wild($3, current_file); } + + +script_file: + { ldgram_in_script = true; } + ifile_list ENDSCRIPT + { ldgram_in_script = false; } + + ; + + +ifile_list: + ifile_list ifile_p1 + | ; @@ -360,6 +358,36 @@ statement_anywhere: | assignment end ; +file_NAME_list: + NAME + { lang_add_wild($1, current_file); } + | file_NAME_list opt_comma NAME + { lang_add_wild($3, current_file); } + ; + +input_section_spec: + NAME + { + lang_add_wild((char *)NULL, $1); + } + | '[' + { + current_file = (char *)NULL; + } + file_NAME_list + ']' + | NAME + { + current_file =$1; + } + '(' file_NAME_list ')' + | '*' + { + current_file = (char *)NULL; + } + '(' file_NAME_list ')' + ; + statement: statement assignment end | statement CREATE_OBJECT_SYMBOLS diff --git a/ld/ldlang.c b/ld/ldlang.c index ec3f5a9f07d..55553fa0ee6 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -37,11 +37,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* EXPORTS */ - +extern char *default_target; extern unsigned int undefined_global_sym_count; -static char *startup_file; +static CONST char *startup_file; static lang_input_statement_type *first_file; lang_statement_list_type statement_list; lang_statement_list_type *stat_ptr = &statement_list; @@ -87,7 +87,7 @@ unsigned int commons_pending; extern args_type command_line; extern ld_config_type config; -char *entry_symbol; +CONST char *entry_symbol; @@ -127,74 +127,148 @@ asection common_section; boolean option_longmap = false; -static void lang_list_init(list) -lang_statement_list_type *list; +/*---------------------------------------------------------------------- + lang_for_each_statement walks the parse tree and calls the provided + function for each node +*/ + +static void +DEFUN(lang_for_each_statement_worker,(func, s), + void (*func)() AND + lang_statement_union_type *s) +{ + for (; s != (lang_statement_union_type *)NULL ; s = s->next) + { + func(s); + + switch (s->header.type) { + case lang_output_section_statement_enum: + lang_for_each_statement_worker + (func, + s->output_section_statement.children.head); + break; + case lang_wild_statement_enum: + lang_for_each_statement_worker + (func, + s->wild_statement.children.head); + break; + case lang_data_statement_enum: + case lang_object_symbols_statement_enum: + case lang_output_statement_enum: + case lang_target_statement_enum: + case lang_input_section_enum: + case lang_input_statement_enum: + case lang_fill_statement_enum: + case lang_assignment_statement_enum: + case lang_padding_statement_enum: + case lang_address_statement_enum: + break; + default: + FAIL(); + break; + } + } +} + +void +DEFUN(lang_for_each_statement,(func), + void (*func)()) +{ + lang_for_each_statement_worker(func, + statement_list.head); +} +/*----------------------------------------------------------------------*/ +static void +DEFUN(lang_list_init,(list), + lang_statement_list_type *list) { list->head = (lang_statement_union_type *)NULL; list->tail = &list->head; } +/*---------------------------------------------------------------------- + Functions to print the link map + */ + static void -print_section(name) -char *name; +DEFUN(print_section,(name), + CONST char *CONST name) { printf("%*s", -longest_section_name, name); } static void -print_space() +DEFUN_VOID(print_space) { printf(" "); } static void -print_nl() +DEFUN_VOID(print_nl) { printf("\n"); } static void -print_address(value) -bfd_vma value; +DEFUN(print_address,(value), + bfd_vma value) { printf("%8lx", value); } static void -print_size(value) -size_t value; +DEFUN(print_size,(value), + size_t value) { printf("%5x", (unsigned)value); } static void -print_alignment(value) -unsigned int value; +DEFUN(print_alignment,(value), + unsigned int value) { printf("2**%2u",value); } + static void -print_fill(value) -fill_type value; +DEFUN(print_fill,(value), + fill_type value) { printf("%04x",(unsigned)value); } +/*---------------------------------------------------------------------- + + build a new statement node for the parse tree + + */ static -lang_statement_union_type *new_statement(type, size, list) -enum statement_enum type; -size_t size; -lang_statement_list_type *list; +lang_statement_union_type* +DEFUN(new_statement,(type, size, list), + enum statement_enum type AND + size_t size AND + lang_statement_list_type *list) { lang_statement_union_type *new = (lang_statement_union_type *) ldmalloc(size); new->header.type = type; new->header.next = (lang_statement_union_type *)NULL; - lang_statement_append(list, new, &new->header.next); + lang_statement_append(list, new, &new->header.next); return new; } +/* + Build a new input file node for the language. There are several ways + in which we treat an input file, eg, we only look at symbols, or + prefix it with a -l etc. + + We can be supplied with requests for input files more than once; + they may, for example be split over serveral lines like foo.o(.text) + foo.o(.data) etc, so when asked for a file we check that we havn't + got it already so we don't duplicate the bfd. + + */ static lang_input_statement_type * -new_afile(name, file_type, target) -char *name; -lang_input_file_enum_type file_type; -char *target; +DEFUN(new_afile, (name, file_type, target), + CONST char *CONST name AND + CONST lang_input_file_enum_type file_type AND + CONST char *CONST target) { lang_input_statement_type *p = new_stat(lang_input_statement, stat_ptr); @@ -216,7 +290,6 @@ char *target; p->local_sym_name= name; p->just_syms_flag = false; p->search_dirs_flag =false; - break; case lang_input_file_is_l_enum: p->is_archive = true; @@ -226,7 +299,6 @@ char *target; p->just_syms_flag = false; p->search_dirs_flag = true; break; - case lang_input_file_is_search_file_enum: case lang_input_file_is_marker_enum: p->filename = name; @@ -236,9 +308,6 @@ char *target; p->just_syms_flag = false; p->search_dirs_flag =true; break; - - - case lang_input_file_is_file_enum: p->filename = name; p->is_archive =false; @@ -247,54 +316,52 @@ char *target; p->just_syms_flag = false; p->search_dirs_flag =false; break; - - default: FAIL(); } p->asymbols = (asymbol **)NULL; p->superfile = (lang_input_statement_type *)NULL; - p->next_real_file = (lang_statement_union_type*)NULL; p->next = (lang_statement_union_type*)NULL; p->symbol_count = 0; p->common_output_section = (asection *)NULL; - lang_statement_append(&input_file_chain, (lang_statement_union_type *)p, &p->next_real_file); return p; } + + lang_input_statement_type * -lang_add_input_file(name, - file_type, - target) -char *name; -lang_input_file_enum_type file_type; -char *target; +DEFUN(lang_add_input_file,(name, file_type, target), + char *name AND + lang_input_file_enum_type file_type AND + char *target) { /* Look it up or build a new one */ - + lang_has_input_file = true; +#if 0 lang_input_statement_type *p; for (p = (lang_input_statement_type *)input_file_chain.head; p != (lang_input_statement_type *)NULL; p = (lang_input_statement_type *)(p->next_real_file)) - { - /* Sometimes we have incomplete entries in here */ - if (p->filename != (char *)NULL) { - if(strcmp(name,p->filename) == 0) return p; - } - } - + { + /* Sometimes we have incomplete entries in here */ + if (p->filename != (char *)NULL) { + if(strcmp(name,p->filename) == 0) return p; + } + + } +#endif return new_afile(name, file_type, target); } - +/* Build enough state so that the parser can build its tree */ void -lang_init() +DEFUN_VOID(lang_init) { stat_ptr= &statement_list; @@ -306,71 +373,61 @@ lang_init() first_file = lang_add_input_file((char *)NULL, lang_input_file_is_marker_enum, (char *)NULL); - } -static void -lang_init2() -{ - script_file = lang_add_input_file("script file", - lang_input_file_is_fake_enum, - (char *)NULL); - script_file->the_bfd = bfd_create("script file", output_bfd); - script_file->symbol_count = 0; - - common_section.userdata = &common_section_userdata; - -} +/*---------------------------------------------------------------------- + A region is an area of memory declared with the + MEMORY { name:org=exp, len=exp ... } + syntax. + We maintain a list of all the regions here -/* this function mainains a dictionary of regions. If the *default* - region is asked for then a pointer to the first region is - returned. If there is no first pointer then one is created + If no regions are specified in the script, then the default is used + which is created when looked up to be the entire data space */ static lang_memory_region_type *lang_memory_region_list; static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list; lang_memory_region_type * -lang_memory_region_lookup(name) -char *name; +DEFUN(lang_memory_region_lookup,(name), + CONST char *CONST name) { - lang_memory_region_type *p = lang_memory_region_list; - for (p = lang_memory_region_list; - p != ( lang_memory_region_type *)NULL; - p = p->next) { - if (strcmp(p->name, name) == 0) { - return p; - } + lang_memory_region_type *p = lang_memory_region_list; + for (p = lang_memory_region_list; + p != ( lang_memory_region_type *)NULL; + p = p->next) { + if (strcmp(p->name, name) == 0) { + return p; } - if (strcmp(name,"*default*")==0) { - /* This is the default region, dig out first one on the list */ - if (lang_memory_region_list != (lang_memory_region_type*)NULL){ - return lang_memory_region_list; - } + } + if (strcmp(name,"*default*")==0) { + /* This is the default region, dig out first one on the list */ + if (lang_memory_region_list != (lang_memory_region_type*)NULL){ + return lang_memory_region_list; } + } { - lang_memory_region_type *new = - (lang_memory_region_type *)ldmalloc(sizeof(lang_memory_region_type)); - new->name = name; - new->next = (lang_memory_region_type *)NULL; - - *lang_memory_region_list_tail = new; - lang_memory_region_list_tail = &new->next; - new->origin = 0; - new->length = ~0; - new->current = 0; - return new; + lang_memory_region_type *new = + (lang_memory_region_type *)ldmalloc(sizeof(lang_memory_region_type)); + new->name = buystring(name); + new->next = (lang_memory_region_type *)NULL; + + *lang_memory_region_list_tail = new; + lang_memory_region_list_tail = &new->next; + new->origin = 0; + new->length = ~0; + new->current = 0; + return new; } } - lang_output_section_statement_type * -lang_output_section_find(name) -char *name; +DEFUN(lang_output_section_find,(name), + CONST char * CONST name) { lang_statement_union_type *u; lang_output_section_statement_type *lookup; @@ -378,19 +435,18 @@ char *name; for (u = lang_output_section_statement.head; u != (lang_statement_union_type *)NULL; u = lookup->next) - { - lookup = &u->output_section_statement; - if (strcmp(name, lookup->name)==0) { - return lookup; + { + lookup = &u->output_section_statement; + if (strcmp(name, lookup->name)==0) { + return lookup; + } } - } return (lang_output_section_statement_type *)NULL; } lang_output_section_statement_type * -lang_output_section_statement_lookup(name) -char *name; - +DEFUN(lang_output_section_statement_lookup,(name), + CONST char * CONST name) { lang_output_section_statement_type *lookup; lookup =lang_output_section_find(name); @@ -421,9 +477,9 @@ char *name; static void - print_flags(outfile, ignore_flags) -FILE *outfile; -lang_section_flags_type *ignore_flags; +DEFUN(print_flags, (outfile, ignore_flags), + FILE *outfile AND + lang_section_flags_type *ignore_flags) { fprintf(outfile,"("); #if 0 @@ -436,8 +492,8 @@ lang_section_flags_type *ignore_flags; } void -lang_map(outfile) - FILE *outfile; +DEFUN(lang_map,(outfile), + FILE *outfile) { lang_memory_region_type *m; fprintf(outfile,"**MEMORY CONFIGURATION**\n\n"); @@ -464,8 +520,9 @@ lang_map(outfile) /* * */ -static void init_os(s) -lang_output_section_statement_type *s; +static void +DEFUN(init_os,(s), + lang_output_section_statement_type *s) { section_userdata_type *new = (section_userdata_type *) @@ -480,12 +537,26 @@ lang_output_section_statement_type *s; get_userdata( s->bfd_section) = new; } +/*********************************************************************** + The wild routines. + + These expand statements like *(.text) and foo.o to a list of + explicit actions, like foo.o(.text), bar.o(.text) and + foo.o(.text,.data) . + + The toplevel routine, wild, takes a statement, section, file and + target. If either the section or file is null it is taken to be the + wildcard. Seperate lang_input_section statements are created for + each part of the expanstion, and placed after the statement provided. + +*/ + static void -wild_doit(ptr, section,output, file) -lang_statement_list_type *ptr; -asection *section; -lang_output_section_statement_type *output; -lang_input_statement_type *file; +DEFUN(wild_doit,(ptr, section, output, file), + lang_statement_list_type *ptr AND + asection *section AND + lang_output_section_statement_type *output AND + lang_input_statement_type *file) { if(output->bfd_section == (asection *)NULL) { @@ -504,82 +575,88 @@ lang_input_statement_type *file; if (section->alignment_power > output->bfd_section->alignment_power) { output->bfd_section->alignment_power = section->alignment_power; } - } } static asection * -our_bfd_get_section_by_name(abfd, section) -bfd *abfd; -char *section; +DEFUN(our_bfd_get_section_by_name,(abfd, section), +bfd *abfd AND +CONST char *section) { return bfd_get_section_by_name(abfd, section); - } + static void -wild_section(ptr, section, file , output) -lang_wild_statement_type *ptr; -char *section; -lang_input_statement_type *file; -lang_output_section_statement_type *output; +DEFUN(wild_section,(ptr, section, file , output), + lang_wild_statement_type *ptr AND + CONST char *section AND + lang_input_statement_type *file AND + lang_output_section_statement_type *output) { asection *s; - if (section == (char *)NULL) { - /* Do the creation to all sections in the file */ - for (s = file->the_bfd->sections; s != (asection *)NULL; s=s->next) { - wild_doit(&ptr->children, s, output, file); + if (file->just_syms_flag == false) { + if (section == (char *)NULL) { + /* Do the creation to all sections in the file */ + for (s = file->the_bfd->sections; s != (asection *)NULL; s=s->next) { + wild_doit(&ptr->children, s, output, file); + } + } + else { + /* Do the creation to the named section only */ + wild_doit(&ptr->children, + our_bfd_get_section_by_name(file->the_bfd, section), + output, file); } } - else { - /* Do the creation to the named section only */ - wild_doit(&ptr->children, - our_bfd_get_section_by_name(file->the_bfd, section), - output, file); - } - - - } +/* passed a file name (which must have been seen already and added to + the statement tree. We will see if it has been opened already and + had its symbols read. If not then we'll read it. + Archives are pecuilar here. We may open them once, but if they do + not define anything we need at the time, they won't have all their + symbols read. If we need them later, we'll have to redo it. + */ static -lang_input_statement_type *lookup_name(name, target) -char *name; -char *target; +lang_input_statement_type * +DEFUN(lookup_name,(name), + CONST char * CONST name) { lang_input_statement_type *search; for(search = (lang_input_statement_type *)input_file_chain.head; search != (lang_input_statement_type *)NULL; search = (lang_input_statement_type *)search->next_real_file) - { - if (search->filename == (char *)NULL && name == (char *)NULL) { - return search; - } - if (search->filename != (char *)NULL && name != (char *)NULL) { - if (strcmp(search->filename, name) == 0) { - Q_read_file_symbols(search); + { + if (search->filename == (char *)NULL && name == (char *)NULL) { return search; } + if (search->filename != (char *)NULL && name != (char *)NULL) { + if (strcmp(search->filename, name) == 0) { + ldmain_open_file_read_symbol(search); + return search; + } + } } - } - /* There isn't an afile entry for this file yet, this must be */ - /* because the name has only appeared inside a load script and not */ - /* on the command line */ - search = new_afile(name, lang_input_file_is_file_enum, target); - Q_read_file_symbols(search); + /* There isn't an afile entry for this file yet, this must be + because the name has only appeared inside a load script and not + on the command line */ + search = new_afile(name, lang_input_file_is_file_enum, default_target); + ldmain_open_file_read_symbol(search); return search; + + } static void - -wild(s, section, file, target, output) -lang_wild_statement_type *s; -char *section; -char *file; -char *target; -lang_output_section_statement_type *output; +DEFUN(wild,(s, section, file, target, output), + lang_wild_statement_type *s AND + CONST char *CONST section AND + CONST char *CONST file AND + CONST char *CONST target AND + lang_output_section_statement_type *output) { lang_input_statement_type *f; if (file == (char *)NULL) { @@ -592,111 +669,103 @@ lang_output_section_statement_type *output; } else { /* Perform the iteration over a single file */ - wild_section( s, section, lookup_name(file, target), output); + wild_section( s, section, lookup_name(file), output); } + if (strcmp(section,"COMMON") == 0 + && default_common_section == (lang_output_section_statement_type*)NULL) + { + /* Remember the section that common is going to incase we later + get something which doesn't know where to put it */ + default_common_section = output; + } } /* read in all the files */ static bfd * -open_output(name, target) -char *name; -char *target; +DEFUN(open_output,(name, target), + CONST char *CONST name AND + CONST char *CONST target) { - extern char *output_filename; + extern CONST char *output_filename; bfd * output = bfd_openw(name, target); output_filename = name; if (output == (bfd *)NULL) - { - if (bfd_error == invalid_target) { - info("%P%F target %s not found\n", target); + { + if (bfd_error == invalid_target) { + info("%P%F target %s not found\n", target); + } + info("%P%F problem opening output file %s, %E", name); } - info("%P%F problem opening output file %s, %E", name); - } output->flags |= D_PAGED; bfd_set_format(output, bfd_object); return output; } -extern char *default_target; + + +static CONST char *current_target; + static void -lang_phase_0(sh,target) -lang_statement_union_type *sh; -char *target; +DEFUN(ldlang_open_output,(statement), + lang_statement_union_type *statement) { - lang_statement_union_type *s = (lang_statement_union_type *)sh; - for (; s != (lang_statement_union_type *)NULL ; s = s->next) - { - switch (s->header.type) { - case lang_output_section_statement_enum: - lang_phase_0(s->output_section_statement.children.head, - target); - break; - case lang_output_statement_enum: -#if 1 - output_bfd = open_output(s->output_statement.name, - target == (char *)NULL ? - default_target : target); + switch (statement->header.type) + { + case lang_output_statement_enum: + output_bfd = open_output(statement->output_statement.name,current_target); ldemul_set_output_arch(); -#endif break; + case lang_target_statement_enum: - target = s->target_statement.target; - break; - case lang_wild_statement_enum: - /* Maybe we should load the file's symbols */ - if (s->wild_statement.filename) { - (void) lookup_name(s->wild_statement.filename, target); - } + current_target = statement->target_statement.target; break; - /* Attatch this to the current output section */ - case lang_common_statement_enum: - case lang_fill_statement_enum: - case lang_input_section_enum: - case lang_object_symbols_statement_enum: - case lang_address_statement_enum: - case lang_data_statement_enum: + default: break; - case lang_afile_asection_pair_statement_enum: + } +} - FAIL(); +static void +DEFUN(open_input_bfds,(statement), + lang_statement_union_type *statement) +{ + switch (statement->header.type) + { + case lang_target_statement_enum: + current_target = statement->target_statement.target; break; - - case lang_input_statement_enum: - if (s->input_statement.real == true) { - s->input_statement.target = target; - lookup_name(s->input_statement.filename, target); - } + case lang_wild_statement_enum: + /* Maybe we should load the file's symbols */ + if (statement->wild_statement.filename) + { + (void) lookup_name(statement->wild_statement.filename); + } break; - case lang_assignment_statement_enum: -#if 0 - (void) exp_fold_tree(s->assignment_statement.exp, - output_section, - false); -#endif + case lang_input_statement_enum: + if (statement->input_statement.real == true) + { + statement->input_statement.target = current_target; + lookup_name(statement->input_statement.filename); + } break; - - case lang_padding_statement_enum: - + default: break; } - } - } - /* If there are [COMMONS] statements, put a wild one into the bss section */ static void lang_reasonable_defaults() { - +#if 0 lang_output_section_statement_lookup(".text"); lang_output_section_statement_lookup(".data"); default_common_section = lang_output_section_statement_lookup(".bss"); + if (placed_commons == false) { lang_wild_statement_type *new = new_stat(lang_wild_statement, @@ -705,26 +774,96 @@ lang_reasonable_defaults() new->filename = (char *)NULL; lang_list_init(&new->children); } +#endif } -static void lang() +/* + Add the supplied name to the symbol table as an undefined reference. + Remove items from the chain as we open input bfds + */ +typedef struct ldlang_undef_chain_list_struct { + struct ldlang_undef_chain_list_struct *next; + char *name; +} ldlang_undef_chain_list_type; + +static ldlang_undef_chain_list_type *ldlang_undef_chain_list_head; + +void +DEFUN(ldlang_add_undef,(name), + CONST char *CONST name) { - if (had_script == false) { - parse_line(ldemul_get_script()); + ldlang_undef_chain_list_type *new = + (ldlang_undef_chain_list_type + *)ldmalloc(sizeof(ldlang_undef_chain_list_type)); + + new->next = ldlang_undef_chain_list_head; + ldlang_undef_chain_list_head = new; + + new->name = buystring(name); +} +/* Run through the list of undefineds created above and place them + into the linker hash table as undefined symbols belonging to the + script file. +*/ +static void +DEFUN_VOID(lang_place_undefineds) +{ + ldlang_undef_chain_list_type *ptr = ldlang_undef_chain_list_head; + while (ptr != (ldlang_undef_chain_list_type*)NULL) { + ldsym_type *sy = ldsym_get(ptr->name); + asymbol *def; + asymbol **def_ptr = (asymbol **)ldmalloc(sizeof(asymbol **)); + def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd); + *def_ptr= def; + def->name = ptr->name; + def->flags = BSF_UNDEFINED; + def->section = (asection *)NULL; + Q_enter_global_ref(def_ptr); + ptr = ptr->next; } +} - lang_reasonable_defaults(); - lang_phase_0(statement_list.head,default_target); + + +/* Copy important data from out internal form to the bfd way. Also + create a section for the dummy file + */ + +static void +DEFUN_VOID(lang_create_output_section_statements) +{ + lang_statement_union_type*os; + for (os = lang_output_section_statement.head; + os != (lang_statement_union_type*)NULL; + os = os->output_section_statement.next) { + lang_output_section_statement_type *s = + &os->output_section_statement; + init_os(s); + } + +} + +static void +DEFUN_VOID(lang_init_script_file) +{ + script_file = lang_add_input_file("script file", + lang_input_file_is_fake_enum, + (char *)NULL); + script_file->the_bfd = bfd_create("script file", output_bfd); + script_file->symbol_count = 0; + script_file->the_bfd->sections = output_bfd->sections; } + + /* Open input files and attatch to output sections */ static void -lang_open_input(s, target, output_section_statement) -lang_statement_union_type *s; -char *target; -lang_output_section_statement_type *output_section_statement; +DEFUN(map_input_to_output_sections,(s, target, output_section_statement), + lang_statement_union_type *s AND + CONST char *target AND + lang_output_section_statement_type *output_section_statement) { for (; s != (lang_statement_union_type *)NULL ; s = s->next) { @@ -737,7 +876,7 @@ lang_output_section_statement_type *output_section_statement; break; case lang_output_section_statement_enum: - lang_open_input(s->output_section_statement.children.head, + map_input_to_output_sections(s->output_section_statement.children.head, target, &s->output_section_statement); break; @@ -746,20 +885,16 @@ lang_output_section_statement_type *output_section_statement; case lang_target_statement_enum: target = s->target_statement.target; break; - case lang_common_statement_enum: case lang_fill_statement_enum: case lang_input_section_enum: case lang_object_symbols_statement_enum: case lang_data_statement_enum: + case lang_assignment_statement_enum: + case lang_padding_statement_enum: break; case lang_afile_asection_pair_statement_enum: FAIL(); break; - - case lang_assignment_statement_enum: - case lang_padding_statement_enum: - - break; case lang_address_statement_enum: /* Mark the specified section with the supplied address */ { @@ -771,7 +906,7 @@ lang_output_section_statement_type *output_section_statement; break; case lang_input_statement_enum: /* A standard input statement, has no wildcards */ - /* Q_read_file_symbols(&s->input_statement);*/ + /* ldmain_open_file_read_symbol(&s->input_statement);*/ break; } } @@ -782,8 +917,8 @@ lang_output_section_statement_type *output_section_statement; static void -print_output_section_statement(output_section_statement) -lang_output_section_statement_type *output_section_statement; +DEFUN(print_output_section_statement,(output_section_statement), + lang_output_section_statement_type *output_section_statement) { asection *section = output_section_statement->bfd_section; print_nl(); @@ -816,9 +951,9 @@ lang_output_section_statement_type *output_section_statement; } static void -print_assignment(assignment, output_section) -lang_assignment_statement_type *assignment; -lang_output_section_statement_type *output_section; +DEFUN(print_assignment,(assignment, output_section), + lang_assignment_statement_type *assignment AND + lang_output_section_statement_type *output_section) { etree_value_type result; print_section(""); @@ -837,23 +972,24 @@ lang_output_section_statement_type *output_section; print_address(result.value); } else - { - printf("*undefined*"); - } + { + printf("*undefined*"); + } print_space(); exp_print_tree(stdout, assignment->exp); printf("\n"); } static void -print_input_statement(statm) -lang_input_statement_type *statm; +DEFUN(print_input_statement,(statm), + lang_input_statement_type *statm) { printf("LOAD %s\n",statm->filename); } -static void print_symbol(q) -asymbol *q; +static void +DEFUN(print_symbol,(q), + asymbol *q) { print_section(""); printf(" "); @@ -863,9 +999,10 @@ asymbol *q; printf(" %s", q->name ? q->name : " "); print_nl(); } + static void -print_input_section(in) -lang_input_section_type *in; +DEFUN(print_input_section,(in), + lang_input_section_type *in) { asection *i = in->section; @@ -882,7 +1019,12 @@ lang_input_section_type *in; print_alignment(i->alignment_power); printf(" "); if (in->ifile) { + bfd *abfd = in->ifile->the_bfd; + if (in->ifile->just_syms_flag == true) { + printf("symbols only "); + } + printf(" %s ",abfd->xvec->name); if(abfd->my_archive != (bfd *)NULL) { printf("[%s]%s", abfd->my_archive->filename, @@ -894,16 +1036,16 @@ lang_input_section_type *in; print_nl(); /* Find all the symbols in this file defined in this section */ - { - asymbol **p; - for (p = in->ifile->asymbols; *p; p++) { - asymbol *q = *p; + { + asymbol **p; + for (p = in->ifile->asymbols; *p; p++) { + asymbol *q = *p; - if (bfd_get_section(q) == i && q->flags & BSF_GLOBAL) { - print_symbol(q); + if (bfd_get_section(q) == i && q->flags & BSF_GLOBAL) { + print_symbol(q); + } } } - } } else { print_nl(); @@ -917,50 +1059,18 @@ lang_input_section_type *in; } } } -static void -print_common_statement() -{ - ldsym_type *lgs; - print_section(""); - print_space(); - print_section(common_section.output_section->name); - print_space(); - print_address(common_section.output_offset + - common_section.output_section->vma); - print_space(); - print_size(common_section.size); - print_space(); - printf("(common)"); - print_nl(); - /* Print out all the global symbols */ - - - for (lgs = symbol_head; lgs != (ldsym_type *)NULL; lgs = - lgs->next) { - if (lgs->sdefs_chain) { - asymbol *def = *(lgs->sdefs_chain); - if (def->section == &common_section) { - print_symbol(def); - } - } - - } - print_dot = common_section.output_offset + - common_section.output_section->vma + common_section.size; - -} static void -print_fill_statement(fill) -lang_fill_statement_type *fill; +DEFUN(print_fill_statement,(fill), + lang_fill_statement_type *fill) { printf("FILL mask "); print_fill( fill->fill); } static void -print_data_statement(data) -lang_data_statement_type *data; +DEFUN(print_data_statement,(data), + lang_data_statement_type *data) { /* bfd_vma value; */ print_section(""); @@ -995,8 +1105,8 @@ lang_data_statement_type *data; static void -print_padding_statement(s) -lang_padding_statement_type *s; +DEFUN(print_padding_statement,(s), + lang_padding_statement_type *s) { print_section(""); print_space(); @@ -1010,9 +1120,10 @@ lang_padding_statement_type *s; print_nl(); } -static void print_wild_statement(w,os) -lang_wild_statement_type *w; -lang_output_section_statement_type *os; +static void +DEFUN(print_wild_statement,(w,os), + lang_wild_statement_type *w AND + lang_output_section_statement_type *os) { if (w->filename != (char *)NULL) { printf("%s",w->filename); @@ -1031,24 +1142,22 @@ lang_output_section_statement_type *os; } static void -print_statement(s, os) -lang_statement_union_type *s; -lang_output_section_statement_type *os; +DEFUN(print_statement,(s, os), + lang_statement_union_type *s AND + lang_output_section_statement_type *os) { while (s) { switch (s->header.type) { case lang_wild_statement_enum: - print_wild_statement(&s->wild_statement, os); - break; + print_wild_statement(&s->wild_statement, os); + break; default: - printf("Fail with %d\n",s->header.type); + printf("Fail with %d\n",s->header.type); FAIL(); break; - case lang_address_statement_enum: - printf("address\n"); - break; - case lang_common_statement_enum: - print_common_statement(); + case lang_address_statement_enum: + printf("address\n"); + break; break; case lang_object_symbols_statement_enum: printf("object symbols\n"); @@ -1059,8 +1168,6 @@ lang_output_section_statement_type *os; case lang_data_statement_enum: print_data_statement(&s->data_statement); break; - - case lang_input_section_enum: print_input_section(&s->input_section); break; @@ -1072,7 +1179,7 @@ lang_output_section_statement_type *os; break; case lang_assignment_statement_enum: print_assignment(&s->assignment_statement, - os); + os); break; @@ -1095,19 +1202,19 @@ lang_output_section_statement_type *os; static void -print_statements() +DEFUN_VOID(print_statements) { print_statement(statement_list.head, (lang_output_section_statement_type *)NULL); } static bfd_vma -insert_pad(this_ptr, fill, power, output_section_statement, dot) -lang_statement_union_type **this_ptr; -fill_type fill; -unsigned int power; -asection * output_section_statement; -bfd_vma dot; +DEFUN(insert_pad,(this_ptr, fill, power, output_section_statement, dot), + lang_statement_union_type **this_ptr AND + fill_type fill AND + unsigned int power AND + asection * output_section_statement AND + bfd_vma dot) { /* Align this section first to the input sections requirement, then @@ -1145,119 +1252,18 @@ bfd_vma dot; } -/* - size_common runs run though each global symboxl, and works - out how big the common section will be. - */ - +/* Work out how much this section will move the dot point */ static bfd_vma -size_common(output_section_statement, this_ptr, dot) -lang_output_section_statement_type *output_section_statement; -lang_statement_union_type **this_ptr; -bfd_vma dot; -{ - extern ldsym_type *symbol_head; - ldsym_type *sp; - /* Make sure that each symbol is only defined once. - Allocate common symbols - Make the ref chain point to the defining asymbol. - */ - /* Now, for each symbol, verify that it is defined globally at most once. - Put the global value into the symbol entry. - Common symbols are allocated here, in the BSS section. - Each defined symbol is given a '->defined' field - which is the correct N_ code for its definition, - except in the case of common symbols with -r. - Then make all the references point at the symbol entry - instead of being chained together. */ - - - common_section.name = output_section_statement->bfd_section->name; - common_section.output_section = output_section_statement->bfd_section; - common_section.output_offset = - dot - output_section_statement->bfd_section->vma; - if (config.relocateable_output == false || - command_line.force_common_definition== true) { - dot = insert_pad(this_ptr, - 0x0, 4, output_section_statement->bfd_section, dot); - - for (sp = symbol_head; sp != (ldsym_type *)NULL; sp = sp->next) - { - /* Attatch this symbol to the correct output section*/ - - /* Allocate as common if wanted */ - - if (sp->scoms_chain ) - - { - unsigned long com = (*(sp->scoms_chain))->value; - /* Work out what alignment this common item s - hould be put on. Anything < int is int aligned, - anything bigger is self aligned, - up to the restriction of the machine */ - - unsigned int align = sizeof(int); - - /* Round up size of object to nearest int */ - com = ALIGN(com, sizeof(int)); - /* See what alignment is necessary -*/ - if (com) { - while ((com & align)==0) align <<=1; - /* FIXME */ - if (align > 8) { - align = 8; - } - } - dot = ALIGN(dot, align); - - - /* Transmogrify this from a common symbol - into a definition of a symbol in common - */ - sp->sdefs_chain = sp->scoms_chain; - - { - asymbol *com_ptr = *(sp->sdefs_chain); - - sp->scoms_chain = (asymbol **)NULL; - commons_pending--; - /* Assign address, but keep section relative */ - - /* Force the symbol to belong in the bss section */ - com_ptr->flags = BSF_EXPORT | BSF_GLOBAL ; - com_ptr->section = &common_section; - common_section.size += com; - if (write_map) - { - printf ("Allocating common %s: %lx at %lx\n", - sp->name, - com, - com_ptr->value); - } - com_ptr->value = common_section.size; - } - } - } - } - if (dot > - (common_section.output_section->vma + - common_section.output_section->size)) { - common_section.output_section->size = - dot - common_section.output_section->vma; - } - return dot + common_section.size; -} - -static bfd_vma -size_input_section( this_ptr, output_section_statement, fill, dot) -lang_statement_union_type **this_ptr; -lang_output_section_statement_type*output_section_statement; -unsigned short fill; -bfd_vma dot; +DEFUN(size_input_section, (this_ptr, output_section_statement, fill, dot), + lang_statement_union_type **this_ptr AND + lang_output_section_statement_type*output_section_statement AND + unsigned short fill AND + bfd_vma dot) { lang_input_section_type *is = &((*this_ptr)->input_section); asection *i = is->section; - + + if (is->ifile->just_syms_flag == false) { dot = insert_pad(this_ptr, fill, i->alignment_power, output_section_statement->bfd_section, dot); @@ -1274,7 +1280,7 @@ bfd_vma dot; dot += i->size; output_section_statement->bfd_section->size = dot - output_section_statement->bfd_section->vma; - +} return dot ; } @@ -1283,185 +1289,179 @@ bfd_vma dot; /* Work out the size of the output sections from the sizes of the input sections */ static bfd_vma -lang_size_sections(s, output_section_statement, prev, fill, dot) -lang_statement_union_type *s; -lang_output_section_statement_type * output_section_statement; -lang_statement_union_type **prev; -unsigned short fill; -bfd_vma dot; +DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot), + lang_statement_union_type *s AND + lang_output_section_statement_type * output_section_statement AND + lang_statement_union_type **prev AND + unsigned short fill AND + bfd_vma dot) { /* Size up the sections from their constituent parts */ for (; s != (lang_statement_union_type *)NULL ; s = s->next) - { - switch (s->header.type) { - case lang_output_section_statement_enum: - { - bfd_vma after; - lang_output_section_statement_type *os = - &(s->output_section_statement); - /* The start of a section */ + { + switch (s->header.type) { + case lang_output_section_statement_enum: + { + bfd_vma after; + lang_output_section_statement_type *os = + &(s->output_section_statement); + /* The start of a section */ - if (os->addr_tree == (etree_type *)NULL) { - /* No address specified for this section, get one - from the region specification - */ - if (os->region == (lang_memory_region_type *)NULL) { + if (os->addr_tree == (etree_type *)NULL) { + /* No address specified for this section, get one + from the region specification + */ + if (os->region == (lang_memory_region_type *)NULL) { os->region = lang_memory_region_lookup("*default*"); + } + dot = os->region->current; } - dot = os->region->current; - } - else { - etree_value_type r ; - r = exp_fold_tree(os->addr_tree, - (lang_output_section_statement_type *)NULL, - lang_allocating_phase_enum, - dot, &dot); - if (r.valid == false) { - info("%F%S: non constant address expression for section %s\n", - os->name); - } - dot = r.value; - } - /* The section starts here */ - /* First, align to what the section needs */ + else { + etree_value_type r ; + r = exp_fold_tree(os->addr_tree, + (lang_output_section_statement_type *)NULL, + lang_allocating_phase_enum, + dot, &dot); + if (r.valid == false) { + info("%F%S: non constant address expression for section %s\n", + os->name); + } + dot = r.value; + } + /* The section starts here */ + /* First, align to what the section needs */ - dot = align_power(dot, os->bfd_section->alignment_power); - os->bfd_section->vma = dot; - os->bfd_section->output_offset = 0; + dot = align_power(dot, os->bfd_section->alignment_power); + os->bfd_section->vma = dot; + os->bfd_section->output_offset = 0; - (void) lang_size_sections(os->children.head, os, &os->children.head, - os->fill, dot); - /* Ignore the size of the input sections, use the vma and size to */ - /* align against */ + (void) lang_size_sections(os->children.head, os, &os->children.head, + os->fill, dot); + /* Ignore the size of the input sections, use the vma and size to */ + /* align against */ - after = ALIGN(os->bfd_section->vma + - os->bfd_section->size, - os->block_value) ; + after = ALIGN(os->bfd_section->vma + + os->bfd_section->size, + os->block_value) ; - os->bfd_section->size = after - os->bfd_section->vma; - dot = os->bfd_section->vma + os->bfd_section->size; - os->processed = true; + os->bfd_section->size = after - os->bfd_section->vma; + dot = os->bfd_section->vma + os->bfd_section->size; + os->processed = true; - /* Replace into region ? */ - if (os->addr_tree == (etree_type *)NULL - && os->region !=(lang_memory_region_type*)NULL ) { - os->region->current = dot; - } - } + /* Replace into region ? */ + if (os->addr_tree == (etree_type *)NULL + && os->region !=(lang_memory_region_type*)NULL ) { + os->region->current = dot; + } + } - break; + break; - case lang_data_statement_enum: - { - unsigned int size; - s->data_statement.output_vma = dot; - s->data_statement.output_section = - output_section_statement->bfd_section; + case lang_data_statement_enum: + { + unsigned int size; + s->data_statement.output_vma = dot; + s->data_statement.output_section = + output_section_statement->bfd_section; - switch (s->data_statement.type) { - case LONG: - size = LONG_SIZE; - break; - case SHORT: - size = SHORT_SIZE; - break; - case BYTE: - size = BYTE_SIZE; - break; + switch (s->data_statement.type) { + case LONG: + size = LONG_SIZE; + break; + case SHORT: + size = SHORT_SIZE; + break; + case BYTE: + size = BYTE_SIZE; + break; - } - dot += size; - output_section_statement->bfd_section->size += size; - } - break; + } + dot += size; + output_section_statement->bfd_section->size += size; + } + break; - case lang_wild_statement_enum: + case lang_wild_statement_enum: - dot = lang_size_sections(s->wild_statement.children.head, + dot = lang_size_sections(s->wild_statement.children.head, output_section_statement, &s->wild_statement.children.head, fill, dot); - break; - - case lang_object_symbols_statement_enum: - create_object_symbols = output_section_statement; - break; - case lang_output_statement_enum: - - case lang_target_statement_enum: - break; - case lang_common_statement_enum: - dot = size_common(output_section_statement, prev, dot); - - break; + break; - case lang_input_section_enum: - dot = size_input_section(prev, + case lang_object_symbols_statement_enum: + create_object_symbols = output_section_statement; + break; + case lang_output_statement_enum: + case lang_target_statement_enum: + break; + case lang_input_section_enum: + dot = size_input_section(prev, output_section_statement, output_section_statement->fill, dot); - break; - case lang_input_statement_enum: - break; - case lang_fill_statement_enum: - fill = s->fill_statement.fill; - break; - case lang_assignment_statement_enum: - { - bfd_vma newdot = dot; - exp_fold_tree(s->assignment_statement.exp, - output_section_statement, - lang_allocating_phase_enum, - dot, - &newdot); - - if (newdot != dot) - /* We've been moved ! so insert a pad */ + break; + case lang_input_statement_enum: + break; + case lang_fill_statement_enum: + fill = s->fill_statement.fill; + break; + case lang_assignment_statement_enum: { - lang_statement_union_type *new = - (lang_statement_union_type *) - ldmalloc(sizeof(lang_padding_statement_type)); - /* Link into existing chain */ - new->header.next = *prev; - *prev = new; - new->header.type = lang_padding_statement_enum; - new->padding_statement.output_section = - output_section_statement->bfd_section; - new->padding_statement.output_offset = - dot - output_section_statement->bfd_section->vma; - new->padding_statement.fill = fill; - new->padding_statement.size = newdot - dot; - output_section_statement->bfd_section->size += - new->padding_statement.size; - dot = newdot; + bfd_vma newdot = dot; + exp_fold_tree(s->assignment_statement.exp, + output_section_statement, + lang_allocating_phase_enum, + dot, + &newdot); + + if (newdot != dot) + /* We've been moved ! so insert a pad */ + { + lang_statement_union_type *new = + (lang_statement_union_type *) + ldmalloc(sizeof(lang_padding_statement_type)); + /* Link into existing chain */ + new->header.next = *prev; + *prev = new; + new->header.type = lang_padding_statement_enum; + new->padding_statement.output_section = + output_section_statement->bfd_section; + new->padding_statement.output_offset = + dot - output_section_statement->bfd_section->vma; + new->padding_statement.fill = fill; + new->padding_statement.size = newdot - dot; + output_section_statement->bfd_section->size += + new->padding_statement.size; + dot = newdot; + } } - } - break; - case lang_padding_statement_enum: - FAIL(); - break; - default: - FAIL(); - break; - case lang_address_statement_enum: - break; + break; + case lang_padding_statement_enum: + FAIL(); + break; + default: + FAIL(); + break; + case lang_address_statement_enum: + break; + } + prev = &s->header.next; } - prev = &s->header.next; - } return dot; } static bfd_vma -lang_do_assignments(s, output_section_statement, fill, dot) -lang_statement_union_type *s; -lang_output_section_statement_type * output_section_statement; -unsigned short fill; -bfd_vma dot; +DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot), + lang_statement_union_type *s AND + lang_output_section_statement_type * output_section_statement AND + unsigned short fill AND + bfd_vma dot) { for (; s != (lang_statement_union_type *)NULL ; s = s->next) @@ -1487,7 +1487,9 @@ bfd_vma dot; case lang_object_symbols_statement_enum: case lang_output_statement_enum: case lang_target_statement_enum: +#if 0 case lang_common_statement_enum: +#endif break; case lang_data_statement_enum: { @@ -1547,16 +1549,17 @@ bfd_vma dot; -static void lang_relocate_globals() +static void +DEFUN_VOID(lang_relocate_globals) { /* - Each ldsym_type maintains a chain of pointers to asymbols which - references the definition. Replace each pointer to the referenence - with a pointer to only one place, preferably the definition. If - the defintion isn't available then the common symbol, and if - there isn't one of them then choose one reference. - */ + Each ldsym_type maintains a chain of pointers to asymbols which + references the definition. Replace each pointer to the referenence + with a pointer to only one place, preferably the definition. If + the defintion isn't available then the common symbol, and if + there isn't one of them then choose one reference. + */ FOR_EACH_LDSYM(lgs) { asymbol *it; @@ -1570,44 +1573,27 @@ static void lang_relocate_globals() it = *(lgs->srefs_chain); } else { - FAIL(); + /* This can happen when the command line asked for a symbol to + be -u */ + it = (asymbol *)NULL; } if (it != (asymbol *)NULL) - { - asymbol **ptr= lgs->srefs_chain; + { + asymbol **ptr= lgs->srefs_chain; - while (ptr != (asymbol **)NULL) { - asymbol *ref = *ptr; - *ptr = it; - ptr = (asymbol **)(ref->udata); + while (ptr != (asymbol **)NULL) { + asymbol *ref = *ptr; + *ptr = it; + ptr = (asymbol **)(ref->udata); + } } - } } } -/* now that all the jiggery pokery is finished, copy important data from - * out internal form to the bfd way. Also create a section - * for each dummy file - */ - static void -lang_create_output_section_statements() -{ - lang_statement_union_type*os; - for (os = lang_output_section_statement.head; - os != (lang_statement_union_type*)NULL; - os = os->output_section_statement.next) { - lang_output_section_statement_type *s = - &os->output_section_statement; - init_os(s); - } - script_file->the_bfd->sections = output_bfd->sections; -} - -static void -lang_finish() +DEFUN_VOID(lang_finish) { ldsym_type *lgs; @@ -1637,7 +1623,7 @@ lang_finish() /* By now we know the target architecture, and we may have an */ /* ldfile_output_machine_name */ static void -lang_check() +DEFUN_VOID(lang_check) { lang_statement_union_type *file; @@ -1645,39 +1631,39 @@ lang_check() for (file = file_chain.head; file != (lang_statement_union_type *)NULL; file=file->input_statement.next) - { - /* Inspect the architecture and ensure we're linking like - with like - */ - - if (bfd_arch_compatible( file->input_statement.the_bfd, - output_bfd, - &ldfile_output_architecture, - &ldfile_output_machine)) { - bfd_set_arch_mach(output_bfd, - ldfile_output_architecture, ldfile_output_machine); - } - else { - enum bfd_architecture this_architecture = - bfd_get_architecture(file->input_statement.the_bfd); - unsigned long this_machine = - bfd_get_machine(file->input_statement.the_bfd); + { + /* Inspect the architecture and ensure we're linking like + with like + */ + + if (bfd_arch_compatible( file->input_statement.the_bfd, + output_bfd, + &ldfile_output_architecture, + &ldfile_output_machine)) { + bfd_set_arch_mach(output_bfd, + ldfile_output_architecture, ldfile_output_machine); + } + else { + enum bfd_architecture this_architecture = + bfd_get_architecture(file->input_statement.the_bfd); + unsigned long this_machine = + bfd_get_machine(file->input_statement.the_bfd); - info("%I: architecture %s", - file, - bfd_printable_arch_mach(this_architecture, this_machine)); - info(" incompatible with output %s\n", - bfd_printable_arch_mach(ldfile_output_architecture, - ldfile_output_machine)); - ldfile_output_architecture = this_architecture; - ldfile_output_machine = this_machine; - bfd_set_arch_mach(output_bfd, - ldfile_output_architecture, - ldfile_output_machine); + info("%I: architecture %s", + file, + bfd_printable_arch_mach(this_architecture, this_machine)); + info(" incompatible with output %s\n", + bfd_printable_arch_mach(ldfile_output_architecture, + ldfile_output_machine)); + ldfile_output_architecture = this_architecture; + ldfile_output_machine = this_machine; + bfd_set_arch_mach(output_bfd, + ldfile_output_architecture, + ldfile_output_machine); + } } - } } @@ -1687,7 +1673,7 @@ lang_check() */ static void -lang_common() +DEFUN_VOID(lang_common) { ldsym_type *lgs; if (config.relocateable_output == false || @@ -1695,50 +1681,78 @@ lang_common() for (lgs = symbol_head; lgs != (ldsym_type *)NULL; lgs=lgs->next) - { - asymbol *com ; - size_t size; - size_t align; - if (lgs->scoms_chain != (asymbol **)NULL) { - - com = *(lgs->scoms_chain); - size = com->value; - align = sizeof(int); - /* Round up size of object to nearest int */ - size = ALIGN(size, sizeof(int)); - /* Force alignment */ - if (size) { - while ((size & align)==0) align<<=1; - if (align > 8) { + { + asymbol *com ; + unsigned int power_of_two; + size_t size; + size_t align; + if (lgs->scoms_chain != (asymbol **)NULL) { + com = *(lgs->scoms_chain); + size = com->value; + switch (size) { + case 0: + case 1: + align = 1; + power_of_two = 0; + break; + case 2: + power_of_two = 1; + align = 2; + break; + case 3: + case 4: + power_of_two =2; + align = 4; + break; + case 5: + case 6: + case 7: + case 8: + power_of_two = 3; align = 8; + break; + default: + power_of_two = 4; + align = 16; + break; } - } - /* Change from a common symbol into a definition of - a symbol */ - lgs->sdefs_chain = lgs->scoms_chain; - lgs->scoms_chain = (asymbol **)NULL; - commons_pending--; - /* Point to the correct common section */ - com->section = - ((lang_input_statement_type *) - (com->the_bfd->usrdata))->common_section; - /* Fix the size of the common section */ - com->flags = BSF_EXPORT | BSF_GLOBAL; - - if (write_map) - { - printf ("Allocating common %s: %x at %x\n", - lgs->name, - (unsigned) size, - (unsigned) com->section->size); + /* Change from a common symbol into a definition of + a symbol */ + lgs->sdefs_chain = lgs->scoms_chain; + lgs->scoms_chain = (asymbol **)NULL; + commons_pending--; + /* Point to the correct common section */ + com->section = + ((lang_input_statement_type *) + (com->the_bfd->usrdata))->common_section; + /* Fix the size of the common section */ + com->section->size = ALIGN(com->section->size, align); + + /* Remember if this is the biggest alignment ever seen */ + if (power_of_two > com->section->alignment_power) { + com->section->alignment_power = power_of_two; } - com->value = com->section->size; - com->section->size += size; + + + com->flags = BSF_EXPORT | BSF_GLOBAL; + + if (write_map) + { + printf ("Allocating common %s: %x at %x\n", + lgs->name, + (unsigned) size, + (unsigned) com->section->size); + } + com->value = com->section->size; + com->section->size += size; + + } } - } } + + } /* @@ -1748,7 +1762,8 @@ a destination then create an input request and place it into the statement tree. */ -static void lang_place_orphans() +static void +DEFUN_VOID(lang_place_orphans) { lang_input_statement_type *file; for (file = (lang_input_statement_type*)file_chain.head; @@ -1766,8 +1781,19 @@ static void lang_place_orphans() /* This is a lonely common section which must have come from an archive. We attatch to the section with the wildcard */ - wild_doit(&default_common_section->children, s, - default_common_section, file); + if (config.relocateable_output != true + && command_line.force_common_definition == false) { + if (default_common_section == + (lang_output_section_statement_type *)NULL) { + info("%P: No [COMMON] command, defaulting to .bss\n"); + + default_common_section = + lang_output_section_statement_lookup(".bss"); + + } + wild_doit(&default_common_section->children, s, + default_common_section, file); + } } else { lang_output_section_statement_type *os = @@ -1777,56 +1803,14 @@ static void lang_place_orphans() } } } - } } -/* - * phase_2 - * - * peformed after every file has been opened and symbols read - */ -static void -lang_phase_2() -{ - lang_init2(); - - lang_create_output_section_statements(); - lang_open_input(statement_list.head, (char *)NULL, - ( lang_output_section_statement_type *)NULL); - lang_place_orphans(); - lang_common(); - - ldemul_before_allocation(); - - lang_size_sections(statement_list.head, - (lang_output_section_statement_type *)NULL, - &(statement_list.head), 0, (bfd_vma)0); - ldemul_after_allocation(); - /* Do it once again now that we know the sizes of everything */ - - lang_do_assignments(statement_list.head, - (lang_output_section_statement_type *)NULL, - 0, (bfd_vma)0); - - - - lang_check(); - - lang_relocate_globals(); - - - lang_finish(); -} - - - - void -lang_set_flags(ptr, flags) -lang_section_flags_type *ptr; -char *flags; +DEFUN(lang_set_flags,(ptr, flags), + lang_section_flags_type *ptr AND + CONST char *flags) { boolean state = true; ptr->flag_read = false; @@ -1834,52 +1818,52 @@ char *flags; ptr->flag_executable = false; ptr->flag_loadable= false; while (*flags) - { - if (*flags == '!') { - state = false; + { + if (*flags == '!') { + state = false; + flags++; + } + else state = true; + switch (*flags) { + case 'R': + ptr->flag_read = state; + break; + case 'W': + ptr->flag_write = state; + break; + case 'X': + ptr->flag_executable= state; + break; + case 'L': + ptr->flag_loadable= state; + break; + default: + info("%P%F illegal syntax in flags\n"); + break; + } flags++; } - else state = true; - switch (*flags) { - case 'R': - ptr->flag_read = state; - break; - case 'W': - ptr->flag_write = state; - break; - case 'X': - ptr->flag_executable= state; - break; - case 'L': - ptr->flag_loadable= state; - break; - default: - info("%P%F illegal syntax in flags\n"); - break; - } - flags++; - } } void -lang_for_each_file(func) -void (*func)(); +DEFUN(lang_for_each_file,(func), + PROTO(void, (*func),(lang_input_statement_type *))) { lang_input_statement_type *f; for (f = (lang_input_statement_type *)file_chain.head; f != (lang_input_statement_type *)NULL; f = (lang_input_statement_type *)f->next) - { - func(f); - } + { + func(f); + } } void -lang_for_each_input_section(func) -void (*func)(); +DEFUN(lang_for_each_input_section, (func), + PROTO(void ,(*func),(bfd *ab, asection*as))) { lang_input_statement_type *f; for (f = (lang_input_statement_type *)file_chain.head; @@ -1898,10 +1882,10 @@ void (*func)(); void -ldlang_add_file(entry) -lang_input_statement_type *entry; +DEFUN(ldlang_add_file,(entry), + lang_input_statement_type *entry) { - lang_has_input_file = true; + lang_statement_append(&file_chain, (lang_statement_union_type *)entry, &entry->next); @@ -1910,8 +1894,8 @@ lang_input_statement_type *entry; void -lang_add_output(name) -char *name; +DEFUN(lang_add_output,(name), + CONST char *name) { lang_output_statement_type *new = new_stat(lang_output_statement, stat_ptr); @@ -1923,12 +1907,13 @@ char *name; static lang_output_section_statement_type *current_section; void -lang_enter_output_section_statement(output_section_statement_name, -address_exp, -block_value) -char *output_section_statement_name; -etree_type *address_exp; -bfd_vma block_value; +DEFUN(lang_enter_output_section_statement, + (output_section_statement_name, + address_exp, + block_value), + char *output_section_statement_name AND + etree_type *address_exp AND + bfd_vma block_value) { lang_output_section_statement_type *os; current_section = @@ -1953,29 +1938,28 @@ bfd_vma block_value; void -lang_final() +DEFUN_VOID(lang_final) { if (had_output_filename == false) { lang_add_output("a.out"); } - - } -asymbol *create_symbol(name, flags, section) -char *name; -flagword flags; -asection *section; +asymbol * +DEFUN(create_symbol,(name, flags, section), + CONST char *name AND + flagword flags AND + asection *section) { extern lang_input_statement_type *script_file; asymbol **def_ptr = (asymbol **)ldmalloc(sizeof(asymbol **)); /* Add this definition to script file */ asymbol *def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd); - def->name = name; + def->name = buystring(name); def->udata = 0; def->flags = flags; def->section = section; @@ -1987,58 +1971,127 @@ asection *section; void -lang_process() -{ - lang(); - lang_phase_2(); +DEFUN_VOID(lang_process) +{ + if (had_script == false) { + parse_line(ldemul_get_script()); + } + lang_reasonable_defaults(); + current_target = default_target; + + lang_for_each_statement(ldlang_open_output); /* Open the output file */ + /* For each output section statement, create a section in the output + file */ + lang_create_output_section_statements(); + + /* Create a dummy bfd for the script */ + lang_init_script_file(); + + /* Add to the hash table all undefineds on the command line */ + lang_place_undefineds(); + + /* Create a bfd for each input file */ + current_target = default_target; + lang_for_each_statement(open_input_bfds); + + common_section.userdata = &common_section_userdata; + + /* Run through the contours of the script and attatch input sections + to the correct output sections + */ + map_input_to_output_sections(statement_list.head, (char *)NULL, + ( lang_output_section_statement_type *)NULL); + + /* Find any sections not attatched explicitly and handle them */ + lang_place_orphans(); + + /* Size up the common data */ + lang_common(); + + ldemul_before_allocation(); + + /* Size up the sections */ + lang_size_sections(statement_list.head, + (lang_output_section_statement_type *)NULL, + &(statement_list.head), 0, (bfd_vma)0); + + /* See if anything special should be done now we know how big + everything is */ + ldemul_after_allocation(); + + /* Do all the assignments, now that we know the final restingplaces + of all the symbols */ + + lang_do_assignments(statement_list.head, + (lang_output_section_statement_type *)NULL, + 0, (bfd_vma)0); + + /* Make sure that we're not mixing architectures */ + + lang_check(); + + /* Move the global symbols around */ + lang_relocate_globals(); + + /* Final stuffs */ + lang_finish(); } /* EXPORTED TO YACC */ + void -lang_section_start(name, address) -char *name; -etree_type *address; +DEFUN(lang_add_wild,(section_name, filename), + CONST char *CONST section_name AND + CONST char *CONST filename) +{ + lang_wild_statement_type *new = new_stat(lang_wild_statement, + stat_ptr); + + if (section_name != (char *)NULL && strcmp(section_name,"COMMON") == 0) + { + placed_commons = true; + } + if (filename != (char *)NULL) { + lang_has_input_file = true; + } + new->section_name = section_name; + new->filename = filename; + lang_list_init(&new->children); +} +void +DEFUN(lang_section_start,(name, address), + CONST char *name AND + etree_type *address) { lang_address_statement_type *ad =new_stat(lang_address_statement, stat_ptr); ad->section_name = name; ad->address = address; } -void lang_add_entry(name) -char *name; + +void +DEFUN(lang_add_entry,(name), + CONST char *name) { entry_symbol = name; } void -lang_add_target(name) -char *name; +DEFUN(lang_add_target,(name), + CONST char *name) { lang_target_statement_type *new = new_stat(lang_target_statement, stat_ptr); new->target = name; } -void -lang_add_wild(section_name, filename) -char *section_name; -char *filename; -{ - lang_wild_statement_type *new = new_stat(lang_wild_statement, - stat_ptr); - if (section_name != (char *)NULL && strcmp(section_name,"COMMON") == 0) - { - placed_commons = true; - } - new->section_name = section_name; - new->filename = filename; - lang_list_init(&new->children); -} + + void -lang_add_map(name) -char *name; +DEFUN(lang_add_map,(name), + CONST char *name) { while (*name) { switch (*name) { @@ -2050,17 +2103,19 @@ char *name; } } -void lang_add_fill(exp) -int exp; +void +DEFUN(lang_add_fill,(exp), + int exp) { lang_fill_statement_type *new = new_stat(lang_fill_statement, stat_ptr); new->fill = exp; } -void lang_add_data(type, exp) -int type; -union etree_union *exp; +void +DEFUN(lang_add_data,(type, exp), + int type AND + union etree_union *exp) { lang_data_statement_type *new = new_stat(lang_data_statement, @@ -2070,8 +2125,8 @@ union etree_union *exp; } void -lang_add_assignment(exp) -etree_type *exp; +DEFUN(lang_add_assignment,(exp), + etree_type *exp) { lang_assignment_statement_type *new = new_stat(lang_assignment_statement, stat_ptr); @@ -2079,8 +2134,8 @@ etree_type *exp; } void -lang_add_attribute(attribute) -enum statement_enum attribute; +DEFUN(lang_add_attribute,(attribute), + enum statement_enum attribute) { new_statement(attribute, sizeof(lang_statement_union_type),stat_ptr); } @@ -2088,8 +2143,8 @@ enum statement_enum attribute; void -lang_startup(name) -char *name; +DEFUN(lang_startup,(name), + CONST char *name) { if (startup_file != (char *)NULL) { info("%P%FMultiple STARTUP files\n"); @@ -2100,16 +2155,16 @@ char *name; startup_file= name; } void -lang_float(maybe) -boolean maybe; +DEFUN(lang_float,(maybe), + boolean maybe) { lang_float_flag = maybe; } void -lang_leave_output_section_statement(fill, memspec) -bfd_vma fill; -char *memspec; +DEFUN(lang_leave_output_section_statement,(fill, memspec), + bfd_vma fill AND + CONST char *memspec) { current_section->fill = fill; current_section->region = lang_memory_region_lookup(memspec); @@ -2122,9 +2177,9 @@ char *memspec; If the symbol already exists, then do nothing. */ void -lang_abs_symbol_at_beginning_of(section, name) -char *section; -char *name; +DEFUN(lang_abs_symbol_at_beginning_of,(section, name), + CONST char *section AND + CONST char *name) { if (ldsym_undefined(name)) { extern bfd *output_bfd; @@ -2150,9 +2205,9 @@ char *name; If the symbol already exists, then do nothing. */ void -lang_abs_symbol_at_end_of(section, name) -char *section; -char *name; +DEFUN(lang_abs_symbol_at_end_of,(section, name), + CONST char *section AND + CONST char *name) { if (ldsym_undefined(name)){ extern bfd *output_bfd; @@ -2173,59 +2228,14 @@ char *name; } void -lang_statement_append(list, element, field) -lang_statement_list_type *list; -lang_statement_union_type *element; -lang_statement_union_type **field; +DEFUN(lang_statement_append,(list, element, field), + lang_statement_list_type *list AND + lang_statement_union_type *element AND + lang_statement_union_type **field) { *(list->tail) = element; list->tail = field; } -static void -lang_for_each_statement_worker(func, s) -void (*func)(); -lang_statement_union_type *s; -{ - for (; s != (lang_statement_union_type *)NULL ; s = s->next) - { - func(s); - switch (s->header.type) { - case lang_output_section_statement_enum: - lang_for_each_statement_worker - (func, - s->output_section_statement.children.head); - break; - case lang_wild_statement_enum: - lang_for_each_statement_worker - (func, - s->wild_statement.children.head); - break; - case lang_data_statement_enum: - case lang_object_symbols_statement_enum: - case lang_output_statement_enum: - case lang_target_statement_enum: - case lang_common_statement_enum: - case lang_input_section_enum: - case lang_input_statement_enum: - case lang_fill_statement_enum: - case lang_assignment_statement_enum: - case lang_padding_statement_enum: - case lang_address_statement_enum: - break; - default: - FAIL(); - break; - } - } -} - -void lang_for_each_statement(func) -void (*func)(); -{ - lang_for_each_statement_worker(func, - statement_list.head); - -} diff --git a/ld/ldlang.h b/ld/ldlang.h index ab102a50df6..5d8f525eb9c 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -60,7 +60,6 @@ union lang_statement_union *next; lang_address_statement_enum, lang_wild_statement_enum, lang_input_section_enum, - lang_common_statement_enum, lang_object_symbols_statement_enum, lang_fill_statement_enum, lang_data_statement_enum, @@ -83,13 +82,13 @@ typedef struct typedef struct lang_target_statement_struct { lang_statement_header_type header; - char *target; + CONST char *target; } lang_target_statement_type; typedef struct lang_output_statement_struct { lang_statement_header_type header; - char *name; + CONST char *name; } lang_output_statement_type; @@ -98,9 +97,9 @@ typedef struct lang_output_section_statement_struct lang_statement_header_type header; union etree_union *addr_tree; lang_statement_list_type children; - char *memspec; + CONST char *memspec; union lang_statement_union *next; - char *name; + CONST char *name; unsigned long subsection_alignment; boolean processed; @@ -122,7 +121,7 @@ typedef struct { typedef struct { lang_statement_header_type header; -fill_type fill; + fill_type fill; } lang_fill_statement_type; typedef struct { @@ -141,11 +140,11 @@ typedef struct lang_input_statement_struct { lang_statement_header_type header; /* Name of this file. */ - char *filename; + 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. */ - char *local_sym_name; + CONST char *local_sym_name; /* Describe the layout of the contents of the file */ @@ -165,15 +164,6 @@ typedef struct lang_input_statement_struct asymbol **asymbols; unsigned int symbol_count; - /* Next two used only if `relocatable_output' or if needed for */ - /* output of undefined reference line numbers. */ - /* Text reloc info saved by `write_text' for `coptxtrel'. */ - - - /* Offset in bytes in the output file symbol table - of the first local symbol for this file. Set by `write_file_symbols'. */ - int local_syms_offset; - /* For library members only */ /* For a library, points to chain of entries for the library members. */ @@ -187,29 +177,29 @@ typedef struct lang_input_statement_struct 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 */ + /* 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 if file's header has been read into this structure. */ - boolean header_read_flag; - /* 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;*/ - char *target; + CONST char *target; boolean real; asection *common_section; @@ -220,6 +210,7 @@ typedef struct { lang_statement_header_type header; asection *section; lang_input_statement_type *ifile; + } lang_input_section_type; @@ -231,14 +222,14 @@ typedef struct { typedef struct lang_wild_statement_struct { lang_statement_header_type header; - char *section_name; - char *filename; +CONST char *section_name; +CONST char *filename; lang_statement_list_type children; } lang_wild_statement_type; typedef struct lang_address_statement_struct { lang_statement_header_type header; - char *section_name; + CONST char *section_name; union etree_union *address; } lang_address_statement_type; @@ -273,32 +264,34 @@ typedef union lang_statement_union PROTO(void,lang_init,(void)); -PROTO(struct memory_region_struct ,*lang_memory_region_lookup,(char *)); -PROTO(struct lang_output_section_statement_struct *,lang_output_section_find,(char *)); +PROTO(struct memory_region_struct , + *lang_memory_region_lookup,(CONST + char *CONST)); -PROTO(void ,lang_map,(struct _iobuf *)); -PROTO(void,lang_set_flags,(lang_section_flags_type *, char *)); -PROTO(void,lang_add_output,(char *)); + +PROTO(void ,lang_map,(FILE *)); +PROTO(void,lang_set_flags,(lang_section_flags_type *, CONST char *)); +PROTO(void,lang_add_output,(CONST char *)); PROTO(void,lang_final,(void)); -PROTO(struct symbol_cache_entry *,create_symbol,(char *, unsigned int, struct sec_struct *)); +PROTO(struct symbol_cache_entry *,create_symbol,(CONST char *, unsigned int, struct sec_struct *)); PROTO(void ,lang_process,(void)); -PROTO(void ,lang_section_start,(char *, union etree_union *)); -PROTO(void,lang_add_entry,(char *)); -PROTO(void,lang_add_target,(char *)); -PROTO(void,lang_add_wild,(char *, char *)); -PROTO(void,lang_add_map,(char *)); +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,(char *)); +PROTO(void,lang_startup,(CONST char *)); PROTO(void,lang_float,(enum boolean)); -PROTO(void,lang_leave_output_section_statement,(bfd_vma, char *)); -PROTO(void,lang_abs_symbol_at_end_of,(char *, char *)); +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_ASYMBOL(asymbol) \ #define LANG_FOR_EACH_INPUT_STATEMENT(statement) \ extern lang_statement_list_type file_chain; \ @@ -337,11 +330,15 @@ PROTO(void, lang_for_each_file,(void (*dothis)(lang_input_statement_type *))); PROTO(void, lang_process,(void)); PROTO(void, ldlang_add_file,(lang_input_statement_type *)); -PROTO(lang_output_section_statement_type *,lang_output_section_find,()); +PROTO(lang_output_section_statement_type + *,lang_output_section_find,(CONST char * CONST)); PROTO(lang_input_statement_type *, lang_add_input_file,(char *name, lang_input_file_enum_type file_type, char *target)); PROTO(lang_output_section_statement_type *, -lang_output_section_statement_lookup,(char *name)); +lang_output_section_statement_lookup,(CONST char * CONST name)); + +PROTO(void, ldlang_add_undef,(CONST char *CONST name)); + diff --git a/ld/ldlex.l b/ld/ldlex.l index 4710260bd09..2651a050b63 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -28,7 +28,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /*SUPPRESS 529*/ /*SUPPRESS 26*/ /*SUPPRESS 29*/ -#define LEXDEBUG +#define LEXDEBUG 0 #include "sysdep.h" #include "bfd.h" @@ -48,7 +48,7 @@ int debug; extern boolean ldgram_in_expression; extern boolean ldgram_in_defsym; - +extern boolean ldgram_in_script; static char *command_line; extern int fgetc(); @@ -69,6 +69,8 @@ keyword_type keywords[] = "SUBSECTION_ALIGN",SUBSECTION_ALIGN, "ADDR",ADDR, "ENTRY",ENTRY, +"SCRIPT", SCRIPT, +"ENDSCRIPT", ENDSCRIPT, "NEXT",NEXT, "MAP",MAP, "SIZEOF",SIZEOF, @@ -101,17 +103,15 @@ static unsigned int have_pushback; int pushback[NPUSHBACK]; int thischar; extern char *ldfile_input_filename; - +int donehash = 0; int lex_input() { - - if (have_pushback > 0) - { - have_pushback --; - return thischar = pushback[have_pushback]; - } + { + have_pushback --; + return thischar = pushback[have_pushback]; + } if (ldlex_input_stack) { thischar = fgetc(ldlex_input_stack); @@ -119,14 +119,18 @@ lex_input() fclose(ldlex_input_stack); ldlex_input_stack = (FILE *)NULL; ldfile_input_filename = (char *)NULL; - thischar = lex_input(); + /* First char after script eof is a @ so that we can tell the grammer + that we've eft */ + thischar = '@'; } } else if (command_line && *command_line) { thischar = *(command_line++); } - else thischar = 0; + else { + thischar = 0; + } if(thischar == '\t') thischar = ' '; if (thischar == '\n') { thischar = ' '; lineno++; } return thischar ; @@ -213,7 +217,7 @@ long number(text, base) char *text; int base; { -unsigned long l = 0; + unsigned long l = 0; char *p; for (p = text; *p != 0; p++) { if (*p == 'K') { @@ -241,7 +245,7 @@ unsigned long l = 0; %a 4000 %o 5000 -FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+] +FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=] FILENAME {FILENAMECHAR}+ @@ -249,28 +253,30 @@ WHITE [ \t]+ %% - -"\ -defsym" { return OPTION_defsym; } -"\ -noinhibit_exec" { return OPTION_noinhibit_exec; } -"\ -format" { return OPTION_format; } -"\ -n" { return OPTION_n; } -"\ -r" { return OPTION_r; } -"\ -Ur" { return OPTION_Ur; } -"\ -o" { return OPTION_o; } -"\ -g" { return OPTION_g; } -"\ -e" { return OPTION_e; } -"\ -b" { return OPTION_b; } -"\ -dc" { return OPTION_dc; } -"\ -dp" { return OPTION_dp; } -"\ -d" { return OPTION_d; } -"\ -v" { return OPTION_v; } -"\ -M" { return OPTION_M; } -"\ -t" { return OPTION_t; } -"\ -X" { return OPTION_X; } -"\ -x" { return OPTION_x; } -"\ -c" { return OPTION_c; } -"\ -s" { return OPTION_s; } -"\ -S" { return OPTION_S; } +"@" { return ENDSCRIPT; } +"\ -defsym\ " { return OPTION_defsym; } +"\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; } +"\ -format\ " { return OPTION_format; } +"\ -n\ " { return OPTION_n; } +"\ -r\ " { return OPTION_r; } +"\ -Ur\ " { return OPTION_Ur; } +"\ -o\ " { return OPTION_o; } +"\ -g\ " { return OPTION_g; } +"\ -e\ " { return OPTION_e; } +"\ -b\ " { return OPTION_b; } +"\ -dc\ " { return OPTION_dc; } +"\ -dp\ " { return OPTION_dp; } +"\ -d\ " { return OPTION_d; } +"\ -v\ " { return OPTION_v; } +"\ -M\ " { return OPTION_M; } +"\ -t\ " { return OPTION_t; } +"\ -X\ " { return OPTION_X; } +"\ -x\ " { return OPTION_x; } +"\ -c\ " { return OPTION_c; } +"\ -R\ " { return OPTION_R; } +"\ -u\ " { return OPTION_u; } +"\ -s\ " { return OPTION_s; } +"\ -S\ " { return OPTION_S; } "\ -l"{FILENAME} { yylval.name = buystring(yytext+3); return OPTION_l; @@ -280,15 +286,15 @@ WHITE [ \t]+ yylval.name = buystring(yytext+3); return OPTION_L; } -"\ -Ttext" { +"\ -Ttext\ " { yylval.name = ".text"; return OPTION_Texp; } -"\ -Tdata" { +"\ -Tdata\ " { yylval.name = ".data"; return OPTION_Texp; } -"\ -Tbss" { +"\ -Tbss\ " { yylval.name = ".bss"; return OPTION_Texp; } @@ -297,14 +303,14 @@ WHITE [ \t]+ yylval.name = buystring(yytext+3); return OPTION_Tfile; } -"\ -T" { +"\ -T\ " { return OPTION_T; } "\ -F"{FILENAME} { return OPTION_F; } -"\ -F" { +"\ -F\ " { return OPTION_F; } @@ -328,7 +334,6 @@ WHITE [ \t]+ "/=" { RTOKEN(DIVEQ);} "&=" { RTOKEN(ANDEQ);} "|=" { RTOKEN(OREQ);} - "&&" { RTOKEN(ANDAND);} ">" { RTOKEN('>');} "," { RTOKEN(',');} @@ -340,7 +345,6 @@ WHITE [ \t]+ "*" { RTOKEN('*');} "%" { RTOKEN('%');} "<" { RTOKEN('<');} -"+" { RTOKEN('+');} ">" { RTOKEN('>');} "}" { RTOKEN('}') ; } "{" { RTOKEN('{'); } @@ -351,7 +355,7 @@ WHITE [ \t]+ ":" { RTOKEN(':'); } ";" { RTOKEN(';');} "-" { RTOKEN('-');} -"=" { RTOKEN('=');} + "/*" { @@ -412,18 +416,58 @@ WHITE [ \t]+ Tokenize a name, this is really pain, since a name can be a filename or a symbol name. filenames have slashes and stuff whist in an expression those things are seperate tokens. We hack this by - setting lang_in_expression when we are expecting a symbol, so that + setting ldlang_in_script when we are expecting a symbol, so that [/+-] get taken to be seperate tokens. An extra gotcha is expressions after defsyms, we only allow +s and -s in a defsym expression, so -defsym foo=bar+9 /file.o is parsed ok. + The more I think about this the more I hate it. I've got a problem + now with the = sign, what should I do ? imagine: + __start=.; + You'd think that was pretty unambiguous wouldn't you. Well it's + not since __start=. is (at the moment) a perfectly valid + filename. And in some cases we don't know what's going on. I'm + going to have to hack this. If we see a '/' before the = sign then + we say we've got an = in a filename, otherwise it's an operator. + (later) + That's it, I've had enough. From now on, an =s on a command line + will be taken to be part of a file name unless its in a defsym, + and an = in a file will be taken to be an operator. */ int ch; keyword_type *k; + + if (hex_mode) { + ch = yytext[0]; + /* Then always read a number */ + while (isxdigit(ch)) { + yytext[yyleng++] = ch; + ch = input(); + } + yytext[yyleng] = 0; + unput(ch); + + yylval.integer = number(yytext,16); + return INT; + } + + if (ldfile_input_filename) { + /* We're inside a file */ + if (yytext[0]== '=') { + RTOKEN('='); + } + } + + + + /* Otherwise we only notice special things if were in an + expression */ + if (ldgram_in_expression) { if (yytext[0] != '/' || ldgram_in_defsym == false) { switch (yytext[0]) { case '/': RTOKEN('/'); + case '=': RTOKEN('='); case '+': RTOKEN('+'); case '-': RTOKEN('-'); } @@ -433,10 +477,14 @@ WHITE [ \t]+ ch = input(); while (true) { - if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_') { + if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ) { yytext[yyleng++] = ch; } - else if (ch == '+' || ch == '-' || ch == '/') { +else if (ch == '=' && ldgram_in_script) { +/* An = within a script is always taken to be an operator */ +break; +} + else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') { if (ldgram_in_expression) break; yytext[yyleng++] = ch; } @@ -447,7 +495,10 @@ WHITE [ \t]+ yytext[yyleng] = 0; unput(ch); - + /* Filenames of just =signs are tokens */ + if (yyleng == 1 && yytext[0] == '=') { + RTOKEN('='); + } for(k = keywords; k ->name != (char *)NULL; k++) { if (strcmp(k->name, yytext)==0) { diff --git a/ld/ldmain.c b/ld/ldmain.c index 545dcf2ecbc..168a7364fa4 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -21,36 +21,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * * $Id$ * - * $Log$ - * Revision 1.2 1991/03/22 23:02:36 steve - * Brought up to sync with Intel again. - * - * Revision 1.1 1991/03/13 00:48:27 chrisb - * Initial revision - * - * Revision 1.7 1991/03/10 19:15:45 sac - * Fixed a prototype problem - * - * Revision 1.6 1991/03/10 09:31:32 rich - * Modified Files: - * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c - * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h - * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c - * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c - * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h - * - * As of this round of changes, ld now builds on all hosts of (Intel960) - * interest and copy passes my copy test on big endian hosts again. - * - * Revision 1.5 1991/03/09 03:31:02 sac - * After a fatal info message, the output file is deleted. - * - * Revision 1.4 1991/03/06 02:28:31 sac - * Fixed partial linking and error messages. - * - * Revision 1.3 1991/02/22 17:15:02 sac - * Added RCS keywords and copyrights - * * */ @@ -72,7 +42,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* IMPORTS */ extern boolean lang_has_input_file; - +extern boolean trace_files; /* EXPORTS */ char *default_target; @@ -167,7 +137,6 @@ main (argc, argv) char *emulation; program_name = argv[0]; output_filename = "a.out"; - emulation = getenv(EMULATION_ENVIRON); /* Initialize the data about options. */ @@ -198,16 +167,20 @@ main (argc, argv) if (emulation == (char *)NULL) { emulation= DEFAULT_EMULATION; } + + ldemul_choose_mode(emulation); default_target = ldemul_choose_target(); lang_init(); ldemul_before_parse(); - lang_has_input_file = false; parse_args(argc, argv); - + lang_final(); + if (trace_files) { + info("%P: mode %s\n", emulation); + } if (lang_has_input_file == false) { info("%P%F: No input files\n"); } @@ -438,7 +411,6 @@ lang_input_statement_type *entry; if (flag_is_undefined_or_global_or_common(p->flags)) { - Q_enter_global_ref(q); } ASSERT(p->flags != 0); @@ -474,7 +446,7 @@ search_library (entry) void -Q_read_file_symbols (entry) +ldmain_open_file_read_symbol (entry) struct lang_input_statement_struct *entry; { if (entry->asymbols == (asymbol **)NULL @@ -528,7 +500,7 @@ decode_library_subfile (library_entry, subfile_offset) subentry->next = 0; subentry->superfile = library_entry; subentry->is_archive = false; - subentry->header_read_flag = false; + subentry->just_syms_flag = false; subentry->loaded = false; subentry->chain = 0; @@ -773,6 +745,8 @@ struct lang_input_statement_struct *entry; (*(sp->scoms_chain))->udata = (void*)NULL; (*( sp->scoms_chain))->flags = BSF_FORT_COMM; + /* Remember the size of this item */ + sp->scoms_chain[0]->value = p->value; commons_pending++; undefined_global_sym_count--; } { @@ -803,4 +777,3 @@ struct lang_input_statement_struct *entry; return false; } - diff --git a/ld/ldmisc.c b/ld/ldmisc.c index d3671c85db9..f7fc9e97191 100644 --- a/ld/ldmisc.c +++ b/ld/ldmisc.c @@ -32,7 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ld.h" #include "ldmisc.h" #include "ldlang.h" - +#include "ldlex.h" /* IMPORTS */ extern char *program_name; @@ -156,14 +156,14 @@ va_dcl else { int ch; int n = 0; - fprintf(stderr,"command (before <"); + fprintf(stderr,"command (just before \""); ch = lex_input(); while (ch != 0 && n < 10) { fprintf(stderr, "%c", ch); ch = lex_input(); n++; } - fprintf(stderr,")"); + fprintf(stderr,"\")"); } break; @@ -269,8 +269,8 @@ size_t size; -char *buystring(x) -char *x; +char *DEFUN(buystring,(x), + CONST char *CONST x) { size_t l = strlen(x)+1; char *r = ldmalloc(l); diff --git a/ld/ldmisc.h b/ld/ldmisc.h index e3463d1763c..a9391cd0cf3 100644 --- a/ld/ldmisc.h +++ b/ld/ldmisc.h @@ -24,9 +24,9 @@ PROTO(void,info,()); PROTO(void,info_assert,(char *, unsigned int)); PROTO(void,yyerror,(char *)); -PROTO(char *,concat,(char *, char *, char *)); +PROTO(char *,concat,(CONST char *, CONST char *, CONST char *)); PROTO(char *, ldmalloc,(size_t)); -PROTO(char *,buystring,(char *)); +PROTO(char *,buystring,(CONST char *CONST)); #define ASSERT(x) \ { if (!(x)) info_assert(__FILE__,__LINE__); } diff --git a/ld/ldsym.c b/ld/ldsym.c index 986259f5769..5f3a9296013 100644 --- a/ld/ldsym.c +++ b/ld/ldsym.c @@ -19,32 +19,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * $Id$ * - * $Log$ - * Revision 1.3 1991/03/27 02:29:21 steve - * *** empty log message *** - * - * Revision 1.2 1991/03/22 23:02:38 steve - * Brought up to sync with Intel again. - * - * Revision 1.1 1991/03/13 00:48:32 chrisb - * Initial revision - * - * Revision 1.4 1991/03/10 09:31:36 rich - * Modified Files: - * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c - * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h - * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c - * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c - * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h - * - * As of this round of changes, ld now builds on all hosts of (Intel960) - * interest and copy passes my copy test on big endian hosts again. - * - * Revision 1.3 1991/03/06 02:28:56 sac - * Cleaned up - * - * Revision 1.2 1991/02/22 17:15:06 sac - * Added RCS keywords and copyrights * */ diff --git a/ld/ldsym.h b/ld/ldsym.h index 67daed7c797..aeeae31e6f4 100644 --- a/ld/ldsym.h +++ b/ld/ldsym.h @@ -47,11 +47,11 @@ typedef struct user_symbol_struct } ldsym_type; -PROTO(ldsym_type *, ldsym_get, (char *)); -PROTO(ldsym_type *, ldsym_get_soft, (char *)); +PROTO(ldsym_type *, ldsym_get, (CONST char *)); +PROTO(ldsym_type *, ldsym_get_soft, (CONST char *)); PROTO(void, ldsym_print_symbol_table,(void)); PROTO(void, ldsym_write, (void)); -PROTO(boolean, ldsym_undefined, (char *)); +PROTO(boolean, ldsym_undefined, (CONST char *)); #define FOR_EACH_LDSYM(x) \ extern ldsym_type *symbol_head; \ ldsym_type *x; \ diff --git a/ld/ldwrite.c b/ld/ldwrite.c index 93af48c26b6..9beac301727 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -20,17 +20,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * $Id$ * * $Log$ - * Revision 1.3 1991/03/22 22:32:22 steve - * *** empty log message *** + * Revision 1.5 1991/04/14 03:22:42 steve + * checkpoint before a merge * - * Revision 1.2 1991/03/22 22:31:37 steve - * *** empty log message *** - * - * Revision 1.1.1.1 1991/03/21 21:29:05 gumby - * Back from Intel with Steve - * - * Revision 1.1 1991/03/21 21:29:04 gumby - * Initial revision + * Revision 1.4 1991/03/22 23:02:40 steve + * Brought up to sync with Intel again. * * Revision 1.2 1991/03/15 18:45:55 rich * foo @@ -134,7 +128,7 @@ static void perform_relocation(input_bfd, symbols) bfd *input_bfd; asection *input_section; -void *data; +PTR data; asymbol **symbols; { static asymbol *error_symbol = (asymbol *)NULL; @@ -264,104 +258,109 @@ 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); + 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); + /* 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; - switch (statement->data_statement.type) { - case LONG: - bfd_putlong(output_bfd, value, play_area); - size = LONG_SIZE; - break; - case SHORT: - bfd_putshort(output_bfd, value, play_area); - size = SHORT_SIZE; - break; - case BYTE: - bfd_putchar(output_bfd, value, play_area); - size = BYTE_SIZE; - break; - } + { + bfd_vma value = statement->data_statement.value; + bfd_byte play_area[LONG_SIZE]; + unsigned int size; + switch (statement->data_statement.type) { + case LONG: + bfd_putlong(output_bfd, value, play_area); + size = LONG_SIZE; + break; + case SHORT: + bfd_putshort(output_bfd, value, play_area); + size = SHORT_SIZE; + break; + case BYTE: + bfd_putchar(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); + 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; - bfd *inbfd = ifile->the_bfd; - if (output_section->flags & SEC_LOAD && i->size != 0) - { - if(bfd_get_section_contents(inbfd, - i, - data_area, - 0L, - i->size) == false) - { - info("%F%B error reading section contents %E\n", - inbfd); - } - perform_relocation (inbfd, i, data_area, ifile->asymbols); - - - if(bfd_set_section_contents(output_bfd, - output_section, - data_area, - (file_ptr)i->output_offset, - i->size) == false) - { - info("%F%B error writing section contents of %E\n", - output_bfd); - } + { + + 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 && i->size != 0) + { + if(bfd_get_section_contents(inbfd, + i, + data_area, + 0L, + i->size) == false) + { + info("%F%B error reading section contents %E\n", + inbfd); + } + perform_relocation (inbfd, i, data_area, ifile->asymbols); + + + if(bfd_set_section_contents(output_bfd, + output_section, + data_area, + (file_ptr)i->output_offset, + i->size) == false) + { + info("%F%B error writing section contents of %E\n", + output_bfd); + } + } } - } + + } break; - default: + default: /* All the other ones fall through */ ;