diff options
author | Steve Chamberlain <steve@cygnus> | 1991-04-14 03:22:42 +0000 |
---|---|---|
committer | Steve Chamberlain <steve@cygnus> | 1991-04-14 03:22:42 +0000 |
commit | 1418c83b393c2a5d08cc56b306272aab660fbd9d (patch) | |
tree | 607a59985eb915618ca8943a4c0b377ef17a7f72 /ld/ldlang.c | |
parent | da56abdf49af3e87f4b8e105606b0eee7c84b7f1 (diff) | |
download | gdb-1418c83b393c2a5d08cc56b306272aab660fbd9d.zip gdb-1418c83b393c2a5d08cc56b306272aab660fbd9d.tar.gz gdb-1418c83b393c2a5d08cc56b306272aab660fbd9d.tar.bz2 |
checkpoint before a merge
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 1762 |
1 files changed, 886 insertions, 876 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index ec3f5a9..55553fa 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; + current_target = statement->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); - } - 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); -} |