aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog59
-rw-r--r--ld/emultempl/beos.em6
-rw-r--r--ld/emultempl/elf32.em2
-rw-r--r--ld/emultempl/hppaelf.em2
-rw-r--r--ld/emultempl/pe.em7
-rw-r--r--ld/emultempl/ppc64elf.em2
-rw-r--r--ld/ldexp.c90
-rw-r--r--ld/ldexp.h18
-rw-r--r--ld/ldgram.y49
-rw-r--r--ld/ldlang.c59
-rw-r--r--ld/ldlang.h23
-rw-r--r--ld/ldlex.l31
-rw-r--r--ld/ldmain.c2
-rw-r--r--ld/ldwrite.c14
-rw-r--r--ld/pe-dll.c6
15 files changed, 277 insertions, 93 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index c01a5c4..faafddc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,62 @@
+2002-02-15 Alan Modra <amodra@bigpond.net.au>
+
+ Support arbitrary length fill patterns.
+ * ldexp.h (etree_value_type): Add "str" field.
+ (union etree_union): Add "str" to "value" struct.
+ (exp_bigintop): Declare.
+ (exp_get_fill): Declare.
+ * ldexp.c: Include "safe-ctype.h".
+ (exp_intop): Set value.str to NULL.
+ (exp_bigintop): New function.
+ (new_rel): Pass in "str", and set new.str from it.
+ (new_rel_from_section): Set new.str to NULL.
+ (fold_name): Adjust calls to new_rel.
+ (exp_fold_tree): Likewise.
+ (exp_get_fill): New function.
+ * ldgram.y (struct big_int bigint, fill_type *fill): New.
+ (INT): Returns a "bigint". Adjust all code handling INTs.
+ (fill_opt): Returns a "fill".
+ (fill_exp): Split out of fill_opt, use for FILL.
+ * ldlang.h (struct _fill_type): New.
+ (fill_type): Move typedef to ldexp.h.
+ (lang_output_section_statement_type): "fill" is now a pointer.
+ (lang_fill_statement_type): Likewise.
+ (lang_padding_statement_type): Likewise.
+ (lang_add_fill): Now takes a "fill_type *" param.
+ (lang_leave_output_section_statement): Likewise.
+ (lang_do_assignments): Likewise.
+ (lang_size_sections): Likewise.
+ (lang_leave_overlay_section): Likewise.
+ (lang_leave_overlay): Likewise.
+ * ldlang.c: Include ldgram.h after ldexp.h.
+ (lang_output_section_statement_lookup): Adjust for fill_type change.
+ (print_fill_statement): Likewise.
+ (print_padding_statement): Likewise.
+ (insert_pad): Now takes a "fill_type *" arg.
+ (size_input_section): Likewise.
+ (lang_size_sections_1): Likewise.
+ (lang_size_sections): Likewise.
+ (lang_do_assignments): Likewise.
+ (lang_add_fill): Likewise.
+ (lang_leave_output_section_statement): Likewise.
+ (lang_leave_overlay_section): Likewise.
+ (lang_leave_overlay): Likewise.
+ Adjust all callers of the above function.
+ * ldlex.l: Include ldgram.h after ldexp.h. Allow hex numbers
+ starting with "0X" as well as "0x". Return bigint.str for hex
+ numbers starting with "0x" or "0X", zero bigint.str otherwise.
+ Always use base 16 for numbers starting with "$".
+ * ldmain.c: Include ldgram.h after ldexp.h.
+ * ldwrite.c (build_link_order): Use bfd_data_link_order in place
+ of bfd_fill_link_order.
+ * pe-dll.c: Adjust lang_do_assignments calls.
+ * emultempl/elf32.em: Likewise.
+ * emultempl/hppaelf.em: Likewise.
+ * emultempl/ppc64elf.em: Likewise.
+ * emultempl/beos.em: Include ldgram.h after ldexp.h, adjust
+ lang_add_assignment call.
+ * emultempl/pe.em: Likewise.
+
2002-02-14 Phil Edwards <pme@gcc.gnu.org>
* ld.texinfo (VERSION scripts): Symbol names are globbing patterns.
diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em
index cbff05c..e6e6b58 100644
--- a/ld/emultempl/beos.em
+++ b/ld/emultempl/beos.em
@@ -7,7 +7,7 @@ else
fi
cat >e${EMULATION_NAME}.c <<EOF
/* This file is part of GLD, the Gnu Linker.
- Copyright 1995, 1996, 1997, 1998, 2000, 2001
+ Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -38,11 +38,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "libiberty.h"
#include "ld.h"
#include "ldmain.h"
-#include "ldgram.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldemul.h"
+#include "ldgram.h"
#include "ldlex.h"
#include "ldmisc.h"
#include "ldctor.h"
@@ -416,7 +416,7 @@ gld_${EMULATION_NAME}_set_symbols()
for (j = 0; init[j].ptr; j++)
{
long val = init[j].value;
- lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
+ lang_add_assignment (exp_assop ('=', init[j].symbol, exp_intop (val)));
if (init[j].size == sizeof(short))
*(short *)init[j].ptr = val;
else if (init[j].size == sizeof(int))
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index c62727d..675a328 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1341,7 +1341,7 @@ gld${EMULATION_NAME}_finish ()
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head, abs_output_section,
- (fill_type) 0, (bfd_vma) 0);
+ (fill_type *) 0, (bfd_vma) 0);
}
}
EOF
diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em
index 171da12..fd22454 100644
--- a/ld/emultempl/hppaelf.em
+++ b/ld/emultempl/hppaelf.em
@@ -237,7 +237,7 @@ hppaelf_layout_sections_again ()
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head, abs_output_section,
- (fill_type) 0, (bfd_vma) 0);
+ (fill_type *) 0, (bfd_vma) 0);
}
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 2f00269..2aa1eef 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -9,7 +9,7 @@ rm -f e${EMULATION_NAME}.c
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
cat >>e${EMULATION_NAME}.c <<EOF
/* This file is part of GLD, the Gnu Linker.
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -52,11 +52,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "libiberty.h"
#include "ld.h"
#include "ldmain.h"
-#include "ldgram.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldemul.h"
+#include "ldgram.h"
#include "ldlex.h"
#include "ldmisc.h"
#include "ldctor.h"
@@ -708,7 +708,8 @@ gld_${EMULATION_NAME}_set_symbols ()
{
long val = init[j].value;
lang_assignment_statement_type *rv;
- rv = lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
+ rv = lang_add_assignment (exp_assop ('=', init[j].symbol,
+ exp_intop (val)));
if (init[j].size == sizeof(short))
*(short *)init[j].ptr = val;
else if (init[j].size == sizeof(int))
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index 27b20ce..65b824e 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -92,7 +92,7 @@ gld${EMULATION_NAME}_finish ()
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head, abs_output_section,
- (fill_type) 0, (bfd_vma) 0);
+ (fill_type *) 0, (bfd_vma) 0);
}
if (! ppc64_elf_build_stubs (output_bfd, &link_info))
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 4023639..903374e 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1,6 +1,6 @@
/* This module handles expression trees.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001
+ 2001, 2002
Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
@@ -39,6 +39,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ldgram.h"
#include "ldlang.h"
#include "libiberty.h"
+#include "safe-ctype.h"
static void exp_print_token PARAMS ((token_code_type code));
static void make_abs PARAMS ((etree_value_type *ptr));
@@ -46,7 +47,7 @@ static etree_value_type new_abs PARAMS ((bfd_vma value));
static void check PARAMS ((lang_output_section_statement_type *os,
const char *name, const char *op));
static etree_value_type new_rel
- PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
+ PARAMS ((bfd_vma, char *, lang_output_section_statement_type *section));
static etree_value_type new_rel_from_section
PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
static etree_value_type fold_binary
@@ -176,9 +177,22 @@ exp_intop (value)
etree_type *new = (etree_type *) stat_alloc (sizeof (new->value));
new->type.node_code = INT;
new->value.value = value;
+ new->value.str = NULL;
new->type.node_class = etree_value;
return new;
+}
+etree_type *
+exp_bigintop (value, str)
+ bfd_vma value;
+ char *str;
+{
+ etree_type *new = (etree_type *) stat_alloc (sizeof (new->value));
+ new->type.node_code = INT;
+ new->value.value = value;
+ new->value.str = str;
+ new->type.node_class = etree_value;
+ return new;
}
/* Build an expression representing an unnamed relocateable value. */
@@ -197,13 +211,15 @@ exp_relop (section, value)
}
static etree_value_type
-new_rel (value, section)
+new_rel (value, str, section)
bfd_vma value;
+ char *str;
lang_output_section_statement_type *section;
{
etree_value_type new;
new.valid_p = true;
new.value = value;
+ new.str = str;
new.section = section;
return new;
}
@@ -216,6 +232,7 @@ new_rel_from_section (value, section)
etree_value_type new;
new.valid_p = true;
new.value = value;
+ new.str = NULL;
new.section = section;
new.value -= section->bfd_section->vma;
@@ -450,6 +467,7 @@ fold_name (tree, current_section, allocation_done, dot)
being linked with -R? */
result = new_rel ((h->u.def.value
+ h->u.def.section->output_offset),
+ NULL,
os);
}
}
@@ -467,7 +485,7 @@ fold_name (tree, current_section, allocation_done, dot)
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "ADDR");
- result = new_rel (0, os);
+ result = new_rel (0, NULL, os);
}
else
result = invalid ();
@@ -481,7 +499,7 @@ fold_name (tree, current_section, allocation_done, dot)
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "LOADADDR");
if (os->load_base == NULL)
- result = new_rel (0, os);
+ result = new_rel (0, NULL, os);
else
result = exp_fold_tree_no_dot (os->load_base,
abs_output_section,
@@ -532,7 +550,7 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
switch (tree->type.node_class)
{
case etree_value:
- result = new_rel (tree->value.value, current_section);
+ result = new_rel (tree->value.value, tree->value.str, current_section);
break;
case etree_rel:
@@ -542,6 +560,7 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
result = new_rel ((tree->rel.value
+ tree->rel.section->output_section->vma
+ tree->rel.section->output_offset),
+ NULL,
current_section);
break;
@@ -1025,6 +1044,65 @@ exp_get_value_int (tree, def, name, allocation_done)
return (int) exp_get_vma (tree, (bfd_vma) def, name, allocation_done);
}
+fill_type *
+exp_get_fill (tree, def, name, allocation_done)
+ etree_type *tree;
+ fill_type *def;
+ char *name;
+ lang_phase_type allocation_done;
+{
+ fill_type *fill;
+ etree_value_type r;
+ size_t len;
+ unsigned int val;
+
+ if (tree == NULL)
+ return def;
+
+ r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
+ if (! r.valid_p && name != NULL)
+ einfo (_("%F%S nonconstant expression for %s\n"), name);
+
+ if (r.str != NULL && (len = strlen (r.str)) != 0)
+ {
+ unsigned char *dst;
+ unsigned char *s;
+ fill = (fill_type *) xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
+ fill->size = (len + 1) / 2;
+ dst = fill->data;
+ s = r.str;
+ val = 0;
+ do
+ {
+ unsigned int digit;
+
+ digit = *s++ - '0';
+ if (digit > 9)
+ digit = (digit - 'A' + '0' + 10) & 0xf;
+ val <<= 4;
+ val += digit;
+ --len;
+ if ((len & 1) == 0)
+ {
+ *dst++ = val;
+ val = 0;
+ }
+ }
+ while (len != 0);
+ }
+ else
+ {
+ fill = (fill_type *) xmalloc (4 + sizeof (*fill) - 1);
+ val = r.value;
+ fill->data[0] = (val >> 24) & 0xff;
+ fill->data[1] = (val >> 16) & 0xff;
+ fill->data[2] = (val >> 8) & 0xff;
+ fill->data[3] = (val >> 0) & 0xff;
+ fill->size = 4;
+ }
+ return fill;
+}
+
bfd_vma
exp_get_abs_int (tree, def, name, allocation_done)
etree_type *tree;
diff --git a/ld/ldexp.h b/ld/ldexp.h
index fe152d8..edf335d 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -1,5 +1,5 @@
/* ldexp.h -
- Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
+ Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@@ -25,6 +25,7 @@
/* The result of an expression tree */
typedef struct {
bfd_vma value;
+ char *str;
struct lang_output_section_statement_struct *section;
boolean valid_p;
} etree_value_type;
@@ -60,21 +61,21 @@ typedef union etree_union {
} trinary;
struct {
node_type type;
- CONST char *dst;
+ const char *dst;
union etree_union *src;
} assign;
-
struct {
node_type type;
union etree_union *child;
} unary;
struct {
node_type type;
- CONST char *name;
+ const char *name;
} name;
struct {
node_type type;
bfd_vma value;
+ char *str;
} value;
struct {
node_type type;
@@ -98,7 +99,10 @@ extern struct exp_data_seg {
bfd_vma base, end, pagesize;
} exp_data_seg;
+typedef struct _fill_type fill_type;
+
etree_type *exp_intop PARAMS ((bfd_vma));
+etree_type *exp_bigintop PARAMS ((bfd_vma, char *));
etree_type *exp_relop PARAMS ((asection *, bfd_vma));
etree_value_type invalid PARAMS ((void));
etree_value_type exp_fold_tree PARAMS ((etree_type *, struct
@@ -108,13 +112,15 @@ etree_value_type exp_fold_tree PARAMS ((etree_type *, struct
etree_type *exp_binop PARAMS ((int, etree_type *, etree_type *));
etree_type *exp_trinop PARAMS ((int,etree_type *, etree_type *, etree_type *));
etree_type *exp_unop PARAMS ((int, etree_type *));
-etree_type *exp_nameop PARAMS ((int, CONST char *));
-etree_type *exp_assop PARAMS ((int, CONST char *, etree_type *));
+etree_type *exp_nameop PARAMS ((int, const char *));
+etree_type *exp_assop PARAMS ((int, const char *, etree_type *));
etree_type *exp_provide PARAMS ((const char *, etree_type *));
etree_type *exp_assert PARAMS ((etree_type *, const char *));
void exp_print_tree PARAMS ((etree_type *));
bfd_vma exp_get_vma PARAMS ((etree_type *, bfd_vma, char *, lang_phase_type));
int exp_get_value_int PARAMS ((etree_type *, int, char *, lang_phase_type));
+fill_type *exp_get_fill PARAMS ((etree_type *, fill_type *, char *,
+ lang_phase_type));
bfd_vma exp_get_abs_int PARAMS ((etree_type *, int, char *, lang_phase_type));
#endif
diff --git a/ld/ldgram.y b/ld/ldgram.y
index 2df9756..655a726 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -1,6 +1,6 @@
/* A YACC grammar to parse a superset of the AT&T linker scripting language.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001 Free Software Foundation, Inc.
+ 2001, 2002 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
This file is part of GNU ld.
@@ -66,6 +66,12 @@ static int error_index;
%}
%union {
bfd_vma integer;
+ struct big_int
+ {
+ bfd_vma integer;
+ char *str;
+ } bigint;
+ fill_type *fill;
char *name;
const char *cname;
struct wildcard_spec wildcard;
@@ -89,14 +95,14 @@ static int error_index;
%type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
%type <etree> opt_exp_without_type
-%type <integer> fill_opt
+%type <fill> fill_opt fill_exp
%type <name_list> exclude_name_list
%type <wildcard_list> file_NAME_list
%type <name> memspec_opt casesymlist
%type <name> memspec_at_opt
%type <cname> wildcard_name
%type <wildcard> wildcard_spec
-%token <integer> INT
+%token <bigint> INT
%token <name> NAME LNAME
%type <integer> length
%type <phdr> phdr_qualifiers
@@ -230,11 +236,11 @@ mri_script_command:
| ALIAS NAME ',' NAME
{ mri_alias($2,$4,0);}
| ALIAS NAME ',' INT
- { mri_alias($2,0,(int) $4);}
+ { mri_alias ($2, 0, (int) $4.integer); }
| BASE exp
{ mri_base($2); }
- | TRUNCATE INT
- { mri_truncate((unsigned int) $2); }
+ | TRUNCATE INT
+ { mri_truncate ((unsigned int) $2.integer); }
| CASE casesymlist
| EXTERN extern_name_list
| INCLUDE filename
@@ -512,16 +518,12 @@ statement:
| input_section_spec
| length '(' mustbe_exp ')'
{
- lang_add_data((int) $1,$3);
+ lang_add_data ((int) $1, $3);
}
- | FILL '(' mustbe_exp ')'
+ | FILL '(' fill_exp ')'
{
- lang_add_fill
- (exp_get_value_int($3,
- 0,
- "fill value",
- lang_first_phase_enum));
+ lang_add_fill ($3);
}
;
@@ -548,18 +550,21 @@ length:
{ $$ = $1; }
;
-fill_opt:
- '=' mustbe_exp
+fill_exp:
+ mustbe_exp
{
- $$ = exp_get_value_int($2,
- 0,
- "fill value",
- lang_first_phase_enum);
+ $$ = exp_get_fill ($1,
+ 0,
+ "fill value",
+ lang_first_phase_enum);
}
- | { $$ = 0; }
;
-
+fill_opt:
+ '=' fill_exp
+ { $$ = $2; }
+ | { $$ = (fill_type *) 0; }
+ ;
assign_op:
PLUSEQ
@@ -781,7 +786,7 @@ exp :
| DEFINED '(' NAME ')'
{ $$ = exp_nameop(DEFINED, $3); }
| INT
- { $$ = exp_intop($1); }
+ { $$ = exp_bigintop ($1.integer, $1.str); }
| SIZEOF_HEADERS
{ $$ = exp_nameop(SIZEOF_HEADERS,0); }
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 034d122..413ccf8 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -29,9 +29,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ld.h"
#include "ldmain.h"
-#include "ldgram.h"
#include "ldexp.h"
#include "ldlang.h"
+#include "ldgram.h"
#include "ldlex.h"
#include "ldmisc.h"
#include "ldctor.h"
@@ -119,11 +119,11 @@ static void print_statement_list
PARAMS ((lang_statement_union_type *, lang_output_section_statement_type *));
static void print_statements PARAMS ((void));
static void insert_pad
- PARAMS ((lang_statement_union_type **, fill_type,
+ PARAMS ((lang_statement_union_type **, fill_type *,
unsigned int, asection *, bfd_vma));
static bfd_vma size_input_section
PARAMS ((lang_statement_union_type **, lang_output_section_statement_type *,
- fill_type, bfd_vma));
+ fill_type *, bfd_vma));
static void lang_finish PARAMS ((void));
static void ignore_bfd_errors PARAMS ((const char *, ...));
static void lang_check PARAMS ((void));
@@ -152,7 +152,7 @@ static void os_region_check
struct memory_region_struct *, etree_type *, bfd_vma));
static bfd_vma lang_size_sections_1
PARAMS ((lang_statement_union_type *, lang_output_section_statement_type *,
- lang_statement_union_type **, fill_type, bfd_vma, boolean *));
+ lang_statement_union_type **, fill_type *, bfd_vma, boolean *));
typedef void (*callback_t) PARAMS ((lang_wild_statement_type *,
struct wildcard_list *,
@@ -721,7 +721,7 @@ lang_output_section_statement_lookup (name)
new_stat (lang_output_section_statement, stat_ptr);
lookup->region = (lang_memory_region_type *) NULL;
lookup->lma_region = (lang_memory_region_type *) NULL;
- lookup->fill = 0;
+ lookup->fill = (fill_type *) 0;
lookup->block_value = 1;
lookup->name = name;
@@ -2313,7 +2313,12 @@ static void
print_fill_statement (fill)
lang_fill_statement_type *fill;
{
- fprintf (config.map_file, " FILL mask 0x%x\n", fill->fill);
+ size_t size;
+ unsigned char *p;
+ fputs (" FILL mask 0x", config.map_file);
+ for (p = fill->fill->data, size = fill->fill->size; size != 0; p++, size--)
+ fprintf (config.map_file, "%02x", *p);
+ fputs ("\n", config.map_file);
}
static void
@@ -2442,10 +2447,15 @@ print_padding_statement (s)
addr = s->output_offset;
if (s->output_section != NULL)
addr += s->output_section->vma;
- minfo ("0x%V %W", addr, s->size);
+ minfo ("0x%V %W ", addr, s->size);
- if (s->fill != 0)
- minfo (" %u", s->fill);
+ if (s->fill->size != 0)
+ {
+ size_t size;
+ unsigned char *p;
+ for (p = s->fill->data, size = s->fill->size; size != 0; p++, size--)
+ fprintf (config.map_file, "%02x", *p);
+ }
print_nl ();
@@ -2636,11 +2646,12 @@ dprint_statement (s, n)
static void
insert_pad (ptr, fill, alignment_needed, output_section, dot)
lang_statement_union_type **ptr;
- fill_type fill;
+ fill_type *fill;
unsigned int alignment_needed;
asection *output_section;
bfd_vma dot;
{
+ static fill_type zero_fill = { 1, { 0 } };
lang_statement_union_type *pad;
pad = ((lang_statement_union_type *)
@@ -2661,6 +2672,8 @@ insert_pad (ptr, fill, alignment_needed, output_section, dot)
*ptr = pad;
pad->header.type = lang_padding_statement_enum;
pad->padding_statement.output_section = output_section;
+ if (fill == (fill_type *) 0)
+ fill = &zero_fill;
pad->padding_statement.fill = fill;
}
pad->padding_statement.output_offset = dot - output_section->vma;
@@ -2674,7 +2687,7 @@ 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;
- fill_type fill;
+ fill_type *fill;
bfd_vma dot;
{
lang_input_section_type *is = &((*this_ptr)->input_section);
@@ -2831,7 +2844,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
lang_statement_union_type *s;
lang_output_section_statement_type *output_section_statement;
lang_statement_union_type **prev;
- fill_type fill;
+ fill_type *fill;
bfd_vma dot;
boolean *relax;
{
@@ -3207,7 +3220,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
lang_statement_union_type *s;
lang_output_section_statement_type *output_section_statement;
lang_statement_union_type **prev;
- fill_type fill;
+ fill_type *fill;
bfd_vma dot;
boolean *relax;
{
@@ -3242,7 +3255,7 @@ bfd_vma
lang_do_assignments (s, output_section_statement, fill, dot)
lang_statement_union_type *s;
lang_output_section_statement_type *output_section_statement;
- fill_type fill;
+ fill_type *fill;
bfd_vma dot;
{
unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
@@ -4211,7 +4224,7 @@ lang_process ()
section sizes. */
lang_do_assignments (statement_list.head,
abs_output_section,
- (fill_type) 0, (bfd_vma) 0);
+ (fill_type *) 0, (bfd_vma) 0);
/* Perform another relax pass - this time we know where the
globals are, so can make better guess. */
@@ -4235,7 +4248,7 @@ lang_process ()
lang_do_assignments (statement_list.head,
abs_output_section,
- (fill_type) 0, (bfd_vma) 0);
+ (fill_type *) 0, (bfd_vma) 0);
/* Make sure that the section addresses make sense. */
if (! link_info.relocateable
@@ -4351,13 +4364,13 @@ lang_add_map (name)
}
void
-lang_add_fill (exp)
- int exp;
+lang_add_fill (fill)
+ fill_type *fill;
{
lang_fill_statement_type *new = new_stat (lang_fill_statement,
stat_ptr);
- new->fill = exp;
+ new->fill = fill;
}
void
@@ -4444,7 +4457,7 @@ lang_float (maybe)
void
lang_leave_output_section_statement (fill, memspec, phdrs, lma_memspec)
- bfd_vma fill;
+ fill_type *fill;
const char *memspec;
struct lang_output_section_phdr_list *phdrs;
const char *lma_memspec;
@@ -4822,7 +4835,7 @@ lang_enter_overlay_section (name)
void
lang_leave_overlay_section (fill, phdrs)
- bfd_vma fill;
+ fill_type *fill;
struct lang_output_section_phdr_list *phdrs;
{
const char *name;
@@ -4864,7 +4877,7 @@ lang_leave_overlay_section (fill, phdrs)
void
lang_leave_overlay (fill, memspec, phdrs, lma_memspec)
- bfd_vma fill;
+ fill_type *fill;
const char *memspec;
struct lang_output_section_phdr_list *phdrs;
const char *lma_memspec;
@@ -4894,7 +4907,7 @@ lang_leave_overlay (fill, memspec, phdrs, lma_memspec)
{
struct overlay_list *next;
- if (fill != 0 && l->os->fill == 0)
+ if (fill != (fill_type *) 0 && l->os->fill == (fill_type *) 0)
l->os->fill = fill;
/* Assign a region to the sections, if one has been specified.
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 2089591..4e3353a 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -32,7 +32,10 @@ typedef enum {
lang_input_file_is_file_enum
} lang_input_file_enum_type;
-typedef unsigned int fill_type;
+struct _fill_type {
+ size_t size;
+ unsigned char data[1];
+};
typedef struct statement_list {
union lang_statement_union *head;
@@ -125,7 +128,7 @@ typedef struct lang_output_section_statement_struct {
struct memory_region_struct *region;
struct memory_region_struct *lma_region;
size_t block_value;
- fill_type fill;
+ fill_type *fill;
int subsection_alignment; /* alignment of components */
int section_alignment; /* alignment of start of section */
@@ -145,7 +148,7 @@ typedef struct {
typedef struct {
lang_statement_header_type header;
- fill_type fill;
+ fill_type *fill;
int size;
asection *output_section;
} lang_fill_statement_type;
@@ -275,7 +278,7 @@ typedef struct {
bfd_vma output_offset;
size_t size;
asection *output_section;
- fill_type fill;
+ fill_type *fill;
} lang_padding_statement_type;
/* A group statement collects a set of libraries together. The
@@ -385,13 +388,13 @@ extern void lang_add_target PARAMS ((const char *));
extern void lang_add_wild
PARAMS ((struct wildcard_spec *, struct wildcard_list *, boolean));
extern void lang_add_map PARAMS ((const char *));
-extern void lang_add_fill PARAMS ((int));
+extern void lang_add_fill PARAMS ((fill_type *));
extern lang_assignment_statement_type * lang_add_assignment PARAMS ((union etree_union *));
extern void lang_add_attribute PARAMS ((enum statement_enum));
extern void lang_startup PARAMS ((const char *));
extern void lang_float PARAMS ((enum bfd_boolean));
extern void lang_leave_output_section_statement
- PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *,
+ PARAMS ((fill_type *, const char *, struct lang_output_section_phdr_list *,
const char *));
extern void lang_abs_symbol_at_end_of PARAMS ((const char *, const char *));
extern void lang_abs_symbol_at_beginning_of PARAMS ((const char *,
@@ -407,7 +410,7 @@ extern void lang_reset_memory_regions PARAMS ((void));
extern bfd_vma lang_do_assignments
PARAMS ((lang_statement_union_type * s,
lang_output_section_statement_type *output_section_statement,
- fill_type fill,
+ fill_type *fill,
bfd_vma dot));
#define LANG_FOR_EACH_INPUT_STATEMENT(statement) \
@@ -441,7 +444,7 @@ extern void dprint_statement PARAMS ((lang_statement_union_type *, int));
extern bfd_vma lang_size_sections
PARAMS ((lang_statement_union_type *s,
lang_output_section_statement_type *output_section_statement,
- lang_statement_union_type **prev, fill_type fill,
+ lang_statement_union_type **prev, fill_type *fill,
bfd_vma dot, boolean *relax));
extern void lang_enter_group PARAMS ((void));
extern void lang_leave_group PARAMS ((void));
@@ -456,9 +459,9 @@ extern void lang_add_nocrossref PARAMS ((struct lang_nocrossref *));
extern void lang_enter_overlay PARAMS ((etree_type *, etree_type *, int));
extern void lang_enter_overlay_section PARAMS ((const char *));
extern void lang_leave_overlay_section
- PARAMS ((bfd_vma, struct lang_output_section_phdr_list *));
+ PARAMS ((fill_type *, struct lang_output_section_phdr_list *));
extern void lang_leave_overlay
- PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *,
+ PARAMS ((fill_type *, const char *, struct lang_output_section_phdr_list *,
const char *));
extern struct bfd_elf_version_tree *lang_elf_version_info;
diff --git a/ld/ldlex.l b/ld/ldlex.l
index 34fbeca..5300aad 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -38,10 +38,10 @@ This was written by steve chamberlain
#include "sysdep.h"
#include "safe-ctype.h"
#include "ld.h"
-#include "ldgram.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
+#include "ldgram.h"
#include "ldfile.h"
#include "ldlex.h"
#include "ldmain.h"
@@ -153,6 +153,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^]([*?.$_a-zA-Z0-9\[\]\-\!\^]|::)*
<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
yylval.integer = bfd_scan_vma (yytext+1, 0,16);
+ yylval.bigint.str = (char *) 0;
return INT;
}
@@ -178,20 +179,36 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^]([*?.$_a-zA-Z0-9\[\]\-\!\^]|::)*
}
yylval.integer = bfd_scan_vma (yytext, 0,
ibase);
+ yylval.bigint.str = (char *) 0;
return INT;
}
-<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>((("$"|"0x")([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? {
+<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>((("$"|0[xX])([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? {
char *s = yytext;
+ int ibase = 0;
if (*s == '$')
- ++s;
- yylval.integer = bfd_scan_vma (s, 0, 0);
+ {
+ ++s;
+ ibase = 16;
+ }
+ yylval.integer = bfd_scan_vma (s, 0, ibase);
+ yylval.bigint.str = (char *) 0;
if (yytext[yyleng-1] == 'M'
|| yytext[yyleng-1] == 'm')
- yylval.integer *= 1024 * 1024;
- if (yytext[yyleng-1] == 'K'
+ {
+ yylval.integer *= 1024 * 1024;
+ }
+ else if (yytext[yyleng-1] == 'K'
|| yytext[yyleng-1]=='k')
- yylval.integer *= 1024;
+ {
+ yylval.integer *= 1024;
+ }
+ else if (yytext[0] == '0'
+ && (yytext[1] == 'x'
+ || yytext[1] == 'X'))
+ {
+ yylval.bigint.str = xstrdup (yytext + 2);
+ }
return INT;
}
<BOTH,SCRIPT,EXPRESSION,MRI>"]" { RTOKEN(']');}
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 12e31dd..0579727 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -34,9 +34,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ldmain.h"
#include "ldmisc.h"
#include "ldwrite.h"
-#include "ldgram.h"
#include "ldexp.h"
#include "ldlang.h"
+#include "ldgram.h"
#include "ldlex.h"
#include "ldfile.h"
#include "ldemul.h"
diff --git a/ld/ldwrite.c b/ld/ldwrite.c
index e559825..1296a7d 100644
--- a/ld/ldwrite.c
+++ b/ld/ldwrite.c
@@ -1,5 +1,5 @@
/* ldwrite.c -- write out the linked file
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002
Free Software Foundation, Inc.
Written by Steve Chamberlain sac@cygnus.com
@@ -243,9 +243,10 @@ build_link_order (statement)
{
/* We've got a never load section inside one which
is going to be output, we'll change it into a
- fill link_order */
- link_order->type = bfd_fill_link_order;
- link_order->u.fill.value = 0;
+ fill. */
+ link_order->type = bfd_data_link_order;
+ link_order->u.data.contents = "";
+ link_order->u.data.size = 1;
}
else
{
@@ -274,10 +275,11 @@ build_link_order (statement)
if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
{
link_order = bfd_new_link_order (output_bfd, output_section);
- link_order->type = bfd_fill_link_order;
+ link_order->type = bfd_data_link_order;
link_order->size = statement->padding_statement.size;
link_order->offset = statement->padding_statement.output_offset;
- link_order->u.fill.value = statement->padding_statement.fill;
+ link_order->u.data.contents = statement->padding_statement.fill->data;
+ link_order->u.data.size = statement->padding_statement.fill->size;
}
}
break;
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 945564c..7fe46cb 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1,5 +1,5 @@
/* Routines to help build PEI-format DLLs (Win32 etc)
- Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Written by DJ Delorie <dj@cygnus.com>
This file is part of GLD, the Gnu Linker.
@@ -2437,7 +2437,7 @@ pe_dll_fill_sections (abfd, info)
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head,
abs_output_section,
- (fill_type) 0, (bfd_vma) 0);
+ (fill_type *) 0, (bfd_vma) 0);
}
fill_edata (abfd, info);
@@ -2471,7 +2471,7 @@ pe_exe_fill_sections (abfd, info)
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head,
abs_output_section,
- (fill_type) 0, (bfd_vma) 0);
+ (fill_type *) 0, (bfd_vma) 0);
}
reloc_s->contents = reloc_d;
}