diff options
-rw-r--r-- | ld/ldexp.c | 243 | ||||
-rw-r--r-- | ld/ldlang.c | 91 |
2 files changed, 157 insertions, 177 deletions
@@ -375,144 +375,153 @@ bfd_vma *dotp; } else { switch (tree->type.node_class) - { - case etree_value: - result = new_rel(tree->value.value, current_section); - break; - case etree_unary: - result = exp_fold_tree(tree->unary.child, - current_section, - allocation_done, dot, dotp); - if (result.valid == true) - { - switch(tree->type.node_code) + { + case etree_value: + result = new_rel(tree->value.value, current_section); + break; + case etree_unary: + result = exp_fold_tree(tree->unary.child, + current_section, + allocation_done, dot, dotp); + if (result.valid == true) { - case ALIGN_K: - if (allocation_done != lang_first_phase_enum) { - result = new_rel_from_section(ALIGN(dot, - result.value) , - current_section); - - } - else { - result.valid = false; - } - break; - case '-': - result.value = -result.value; - break; - case NEXT: - result.valid = false; - break; - default: - FAIL(); + switch(tree->type.node_code) + { + case ALIGN_K: + if (allocation_done != lang_first_phase_enum) { + result = new_rel_from_section(ALIGN(dot, + result.value) , + current_section); + + } + else { + result.valid = false; + } + break; + case '~': + make_abs(&result); + result.value = ~result.value; + break; + case '!': + make_abs(&result); + result.value = !result.value; + break; + case '-': + make_abs(&result); + result.value = -result.value; + break; + case NEXT: + result.valid = false; + break; + default: + FAIL(); + } } - } - break; - case etree_trinary: + break; + case etree_trinary: - result = exp_fold_tree(tree->trinary.cond, - current_section, - allocation_done, dot, dotp); - if (result.valid) { - result = exp_fold_tree(result.value ? - tree->trinary.lhs:tree->trinary.rhs, + result = exp_fold_tree(tree->trinary.cond, current_section, allocation_done, dot, dotp); - } - - break; - case etree_binary: - result = fold_binary(tree, current_section, allocation_done, - dot, dotp); - break; - case etree_assign: - if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) { - /* Assignment to dot can only be done during allocation */ - if (allocation_done == lang_allocating_phase_enum) { - result = exp_fold_tree(tree->assign.src, + if (result.valid) { + result = exp_fold_tree(result.value ? + tree->trinary.lhs:tree->trinary.rhs, current_section, - lang_allocating_phase_enum, dot, dotp); - if (result.valid == false) { - info("%F%S invalid assignment to location counter\n"); - } - else { - if (current_section == - (lang_output_section_statement_type *)NULL) { - info("%F%S assignment to location counter invalid outside of SECTION\n"); + allocation_done, dot, dotp); + } + + break; + case etree_binary: + result = fold_binary(tree, current_section, allocation_done, + dot, dotp); + break; + case etree_assign: + if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) { + /* Assignment to dot can only be done during allocation */ + if (allocation_done == lang_allocating_phase_enum) { + result = exp_fold_tree(tree->assign.src, + current_section, + lang_allocating_phase_enum, dot, dotp); + if (result.valid == false) { + info("%F%S invalid assignment to location counter\n"); } else { - unsigned long nextdot =result.value + - current_section->bfd_section->vma; - if (nextdot < dot) { - info("%F%S cannot move location counter backwards"); + if (current_section == + (lang_output_section_statement_type *)NULL) { + info("%F%S assignment to location counter invalid outside of SECTION\n"); } else { - *dotp = nextdot; + unsigned long nextdot =result.value + + current_section->bfd_section->vma; + if (nextdot < dot) { + info("%F%S cannot move location counter backwards"); + } + else { + *dotp = nextdot; + } } } } } - } - else { - ldsym_type *sy = ldsym_get(tree->assign.dst); - - /* If this symbol has just been created then we'll place it into - * a section of our choice - */ - result = exp_fold_tree(tree->assign.src, - current_section, allocation_done, - dot, dotp); - if (result.valid) - { - asymbol *def; - asymbol **def_ptr = (asymbol **)ldmalloc(sizeof(asymbol **)); - /* Add this definition to script file */ - def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd); - *def_ptr = def; - - - def->value = result.value; - if (result.section != - (lang_output_section_statement_type *)NULL) { - if (current_section != - (lang_output_section_statement_type *)NULL) { + else { + ldsym_type *sy = ldsym_get(tree->assign.dst); + + /* If this symbol has just been created then we'll place it into + * a section of our choice + */ + result = exp_fold_tree(tree->assign.src, + current_section, allocation_done, + dot, dotp); + if (result.valid) + { + asymbol *def; + asymbol **def_ptr = (asymbol **)ldmalloc(sizeof(asymbol **)); + /* Add this definition to script file */ + def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd); + *def_ptr = def; + + + def->value = result.value; + if (result.section != + (lang_output_section_statement_type *)NULL) { + if (current_section != + (lang_output_section_statement_type *)NULL) { - def->section = result.section->bfd_section; - def->flags = BSF_GLOBAL | BSF_EXPORT; + def->section = result.section->bfd_section; + def->flags = BSF_GLOBAL | BSF_EXPORT; + } + else { + /* Force to absolute */ + def->value += result.section->bfd_section->vma; + def->section = (asection *)NULL; + def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE; + } + + + } + else { + def->section = (asection *)NULL; + def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE; + } + + + def->udata = (PTR)NULL; + def->name = sy->name; + Q_enter_global_ref(def_ptr); } - else { - /* Force to absolute */ - def->value += result.section->bfd_section->vma; - def->section = (asection *)NULL; - def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE; - } - - - } - else { - def->section = (asection *)NULL; - def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE; - } - - def->udata = (PTR)NULL; - def->name = sy->name; - Q_enter_global_ref(def_ptr); - } - - } + } - break; - case etree_name: - result = fold_name(tree, current_section, allocation_done, dot); - break; - default: - info("%F%S Need more of these %d",tree->type.node_class ); + break; + case etree_name: + result = fold_name(tree, current_section, allocation_done, dot); + break; + default: + info("%F%S Need more of these %d",tree->type.node_class ); - } + } } return result; diff --git a/ld/ldlang.c b/ld/ldlang.c index b852dcc..e63f899 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -35,85 +35,56 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ld-emul.h" #include "ldlex.h" -/* EXPORTS */ - -extern char *default_target; - -extern unsigned int undefined_global_sym_count; - -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; -lang_statement_list_type lang_output_section_statement; -lang_statement_list_type input_file_chain; -lang_statement_list_type file_chain; -extern char *current_file; -static boolean placed_commons = false; - -boolean lang_float_flag; - -static lang_output_section_statement_type *default_common_section; - - /* FORWARDS */ PROTO(static void, print_statements,(void)); PROTO(static void, print_statement,(lang_statement_union_type *, lang_output_section_statement_type *)); - +/* LOCALS */ +static CONST char *startup_file; +static lang_statement_list_type input_file_chain; +static boolean placed_commons = false; +static lang_output_section_statement_type *default_common_section; +static boolean map_option_f; +static bfd_vma print_dot; +static lang_input_statement_type *first_file; +static lang_statement_list_type lang_output_section_statement; +static CONST char *current_target; +static CONST char *output_target; +static size_t longest_section_name = 8; +static asection common_section; +static section_userdata_type common_section_userdata; +static lang_statement_list_type statement_list; /* EXPORTS */ -boolean lang_has_input_file = false; +lang_statement_list_type *stat_ptr = &statement_list; +lang_input_statement_type *script_file = 0; +boolean option_longmap = false; +lang_statement_list_type file_chain = {0}; +CONST char *entry_symbol = 0; +size_t largest_section = 0; +boolean lang_has_input_file = false; +lang_output_section_statement_type *create_object_symbols = 0; +boolean had_output_filename = false; +boolean lang_float_flag = false; +/* IMPORTS */ +extern char *default_target; +extern unsigned int undefined_global_sym_count; +extern char *current_file; extern bfd *output_bfd; -size_t largest_section; - - extern enum bfd_architecture ldfile_output_architecture; extern unsigned long ldfile_output_machine; extern char *ldfile_output_machine_name; - - extern ldsym_type *symbol_head; - -bfd_vma print_dot; -unsigned int commons_pending; - - - - +extern unsigned int commons_pending; extern args_type command_line; extern ld_config_type config; - -CONST char *entry_symbol; - - - -lang_output_section_statement_type *create_object_symbols; - extern boolean had_script; -static boolean map_option_f; - - -boolean had_output_filename = false; extern boolean write_map; - - -/* LOCALS */ -static CONST char *current_target; -static CONST char *output_target; -size_t longest_section_name = 8; - - -lang_input_statement_type *script_file; - -section_userdata_type common_section_userdata; -asection common_section; - #ifdef __STDC__ #define cat(a,b) a##b #else @@ -126,7 +97,7 @@ asection common_section; #define outside_symbol_address(q) ((q)->value + outside_section_address(q->section)) -boolean option_longmap = false; + /*---------------------------------------------------------------------- lang_for_each_statement walks the parse tree and calls the provided |