diff options
-rwxr-xr-x | bfd/aout.c | 6 | ||||
-rw-r--r-- | bfd/sunos.c | 6 | ||||
-rw-r--r-- | ld/ld.h | 2 | ||||
-rw-r--r-- | ld/ldgram.y | 5 | ||||
-rw-r--r-- | ld/ldlang.c | 72 | ||||
-rw-r--r-- | ld/ldlang.h | 2 | ||||
-rw-r--r-- | ld/ldlex.l | 1 | ||||
-rw-r--r-- | ld/ldmain.c | 2 |
8 files changed, 54 insertions, 42 deletions
@@ -1249,7 +1249,7 @@ swap_std_reloc_out (abfd, g, natptr) bfd_h_putlong (abfd, g->address, natptr->r_address); - r_length = g->howto->size; /* Size as a power of two */ + r_length = g->howto->size ; /* Size as a power of two */ r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ /* r_baserel, r_jmptable, r_relative??? FIXME-soon */ r_baserel = 0; @@ -1633,14 +1633,14 @@ sunos4_squirt_out_relocs (abfd, section) for (natptr = native; count != 0; --count, natptr += each_size, ++generic) - swap_ext_reloc_out (abfd, generic, (struct reloc_ext_bytes *)native); + swap_ext_reloc_out (abfd, *generic, (struct reloc_ext_bytes *)natptr); } else { for (natptr = native; count != 0; --count, natptr += each_size, ++generic) - swap_std_reloc_out(abfd, generic, (struct reloc_std_bytes *)native); + swap_std_reloc_out(abfd, *generic, (struct reloc_std_bytes *)natptr); } if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { diff --git a/bfd/sunos.c b/bfd/sunos.c index fdc51a5..0c37efd 100644 --- a/bfd/sunos.c +++ b/bfd/sunos.c @@ -1249,7 +1249,7 @@ swap_std_reloc_out (abfd, g, natptr) bfd_h_putlong (abfd, g->address, natptr->r_address); - r_length = g->howto->size; /* Size as a power of two */ + r_length = g->howto->size ; /* Size as a power of two */ r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ /* r_baserel, r_jmptable, r_relative??? FIXME-soon */ r_baserel = 0; @@ -1633,14 +1633,14 @@ sunos4_squirt_out_relocs (abfd, section) for (natptr = native; count != 0; --count, natptr += each_size, ++generic) - swap_ext_reloc_out (abfd, generic, (struct reloc_ext_bytes *)native); + swap_ext_reloc_out (abfd, *generic, (struct reloc_ext_bytes *)natptr); } else { for (natptr = native; count != 0; --count, natptr += each_size, ++generic) - swap_std_reloc_out(abfd, generic, (struct reloc_std_bytes *)native); + swap_std_reloc_out(abfd, *generic, (struct reloc_std_bytes *)natptr); } if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { @@ -85,7 +85,7 @@ typedef struct This is used mainly to finish of sets that were built. */ boolean unix_relocate; - + boolean sort_common; } ld_config_type; #define set_asymbol_chain(x,y) ((x)->udata = (PTR)y) #define get_asymbol_chain(x) ((asymbol **)((x)->udata)) diff --git a/ld/ldgram.y b/ld/ldgram.y index d0196b1..419c54e 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -117,7 +117,7 @@ boolean ldgram_had_equals = false; %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_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S OPTION_sort_common %token OPTION_format OPTION_F OPTION_u %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym @@ -209,6 +209,9 @@ command_line_option: { force_make_executable = true; } + | OPTION_sort_common { + config.sort_common = true; + } | OPTION_d { command_line.force_common_definition = true; } diff --git a/ld/ldlang.c b/ld/ldlang.c index ba165bd..453666d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1659,18 +1659,23 @@ DEFUN_VOID(lang_check) /* * run through all the global common symbols and tie them - * to the output section requested. - */ + * to the output section requested. + * + As an experiment we do this 4 times, once for all the byte sizes, + then all the two bytes, all the four bytes and then everything else + */ static void DEFUN_VOID(lang_common) { ldsym_type *lgs; + size_t power; if (config.relocateable_output == false || command_line.force_common_definition== true) { - for (lgs = symbol_head; - lgs != (ldsym_type *)NULL; - lgs=lgs->next) + for (power = 1; (config.sort_common == true && power == 1) || (power <= 16); power <<=1) { + for (lgs = symbol_head; + lgs != (ldsym_type *)NULL; + lgs=lgs->next) { asymbol *com ; unsigned int power_of_two; @@ -1706,44 +1711,46 @@ DEFUN_VOID(lang_common) align = 16; break; } + if (config.sort_common == false || align == power) { + /* 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; + } + /* Symbol stops being common and starts being global, but + we remember that it was common once. */ - /* 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; - } - - /* Symbol stops being common and starts being global, but - we remember that it was common once. */ - - com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON; - + com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON; + com->value = com->section->size; - if (write_map) + if (write_map) { - printf ("Allocating common %s: %x at %x\n", + printf ("Allocating common %s: %x at %x %s\n", lgs->name, (unsigned) size, - (unsigned) com->section->size); + (unsigned) com->value, + com->the_bfd->filename); } - com->value = com->section->size; - com->section->size += size; + com->section->size += size; + } } + } + } } @@ -1829,6 +1836,7 @@ DEFUN(lang_set_flags,(ptr, flags), ptr->flag_executable= state; break; case 'L': + case 'I': ptr->flag_loadable= state; break; default: diff --git a/ld/ldlang.h b/ld/ldlang.h index ff1c5b1..bfdc9cb 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -274,7 +274,7 @@ 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,(CONST char *, unsigned int, struct sec_struct *)); +PROTO(struct symbol_cache_entry *,create_symbol,(CONST char *, unsigned int, struct sec *)); PROTO(void ,lang_process,(void)); PROTO(void ,lang_section_start,(CONST char *, union etree_union *)); PROTO(void,lang_add_entry,(CONST char *)); @@ -275,6 +275,7 @@ WHITE [ \t]+ "@" { return '}'; } "\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; } "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; } +"\ -sort_common\ " { return OPTION_sort_common;} "\ -format\ " { return OPTION_format; } "\ -n\ " { return OPTION_n; } "\ -r\ " { return OPTION_r; } diff --git a/ld/ldmain.c b/ld/ldmain.c index 2cc9973..7799bfa 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -51,7 +51,7 @@ char *output_filename = "a.out"; char *program_name; /* The file that we're creating */ -bfd *output_bfd; +bfd *output_bfd = 0; extern boolean option_v; |