aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorSteve Chamberlain <steve@cygnus>1991-05-03 23:52:48 +0000
committerSteve Chamberlain <steve@cygnus>1991-05-03 23:52:48 +0000
commitb63165349fd48f5577a3985d7940bcc5377b814d (patch)
tree67b8cda56d2d9787b75c18b02fe81b792542a219 /ld
parent592ecfb22e725acdb1158010b135068f5c87f603 (diff)
downloadgdb-b63165349fd48f5577a3985d7940bcc5377b814d.zip
gdb-b63165349fd48f5577a3985d7940bcc5377b814d.tar.gz
gdb-b63165349fd48f5577a3985d7940bcc5377b814d.tar.bz2
*** empty log message ***
Diffstat (limited to 'ld')
-rw-r--r--ld/ld.h2
-rw-r--r--ld/ldgram.y5
-rw-r--r--ld/ldlang.c72
-rw-r--r--ld/ldlang.h2
-rw-r--r--ld/ldlex.l1
-rw-r--r--ld/ldmain.c2
6 files changed, 48 insertions, 36 deletions
diff --git a/ld/ld.h b/ld/ld.h
index 15577a7..50ee41a 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -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 *));
diff --git a/ld/ldlex.l b/ld/ldlex.l
index 1210555..b1b9619 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -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;