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.
This commit is contained in:
parent
fd96f80fc8
commit
2c382fb6f5
59
ld/ChangeLog
59
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.
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
90
ld/ldexp.c
90
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;
|
||||
|
18
ld/ldexp.h
18
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
|
||||
|
49
ld/ldgram.y
49
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); }
|
||||
|
||||
|
59
ld/ldlang.c
59
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.
|
||||
|
23
ld/ldlang.h
23
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;
|
||||
|
31
ld/ldlex.l
31
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(']');}
|
||||
|
@ -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"
|
||||
|
14
ld/ldwrite.c
14
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user