#define EBMON29K_EMULATION_NAME "ebmon29k"
#define GLDI386AOUT_EMULATION_NAME "gldi386aout"
/* Otherwise default to this emulation */
-#ifndef DEFAULT_EMULATION
-#ifdef GNU960
-#define DEFAULT_EMULATION GLD960_EMULATION_NAME
-#else
-#define DEFAULT_EMULATION GLD68K_EMULATION_NAME
-#endif
-#endif /* DEFAULT_EMULATION */
+
+#define DEFAULT_EMULATION LNK960_EMULATION_NAME
+
/* Look in this variable for a target format */
#define TARGET_ENVIRON "GNUTARGET"
#define GLD_TARGET "a.out-sunos-big"
#define GLD68K_TARGET "a.out-sunos-big"
#define LNK960_TARGET "coff-Intel-big"
+#define LNK960_TARGET_LITTLE "coff-Intel-little"
#define GLD960_TARGET "b.out.big"
#define VANILLA_TARGET "a.out-sunos-big"
#define GLDM88KBCS_TARGET "m88kbcs"
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* This module handles expression trees.
+Copyright (C) 1991 Free Software Foundation, Inc.
+Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
- $Id$
-*/
+This module is in charge of working out the contents of expressions.
-/*
- * Written by Steve Chamberlain
- * steve@cygnus.com
- *
- * This module handles expression trees.
- */
+It has to keep track of the relative/absness of a symbol etc. This is
+done by keeping all values in a struct (an etree_value_type) which
+contains a value, a section to which it is relative and a valid bit.
+
+*/
-#include "sysdep.h"
#include "bfd.h"
+#include "sysdep.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
-#include "ldgram.tab.h"
+#include "ldgram.h"
#include "ldsym.h"
#include "ldlang.h"
extern unsigned int undefined_global_sym_count;
extern unsigned int defined_global_sym_count;
extern bfd *output_bfd;
-extern size_t largest_section;
+extern bfd_size_type largest_section;
extern lang_statement_list_type file_chain;
extern args_type command_line;
extern ld_config_type config;
static void
-exp_print_token(outfile, code)
-FILE *outfile;
-token_code_type code;
+DEFUN(exp_print_token,(outfile, code),
+ FILE *outfile AND
+ token_code_type code)
{
static struct {
token_code_type code;
char *name;
} table[] =
- {
- INT, "int",
- NAME,"NAME",
- PLUSEQ,"+=",
- MINUSEQ,"-=",
- MULTEQ,"*=",
- DIVEQ,"/=",
- LSHIFTEQ,"<<=",
- RSHIFTEQ,">>=",
- ANDEQ,"&=",
- OREQ,"|=",
- OROR,"||",
- ANDAND,"&&",
- EQ,"==",
- NE,"!=",
- LE,"<=",
- GE,">=",
- LSHIFT,"<<",
- RSHIFT,">>=",
- ALIGN_K,"ALIGN",
- BLOCK,"BLOCK",
- SECTIONS,"SECTIONS",
- SIZEOF_HEADERS,"SIZEOF_HEADERS",
- NEXT,"NEXT",
- SIZEOF,"SIZEOF",
- ADDR,"ADDR",
- MEMORY,"MEMORY",
-
-
-
-
-
- DEFINED,"DEFINED",
- TARGET_K,"TARGET",
- SEARCH_DIR,"SEARCH_DIR",
- MAP,"MAP",
- LONG,"LONG",
- SHORT,"SHORT",
- BYTE,"BYTE",
- ENTRY,"ENTRY",
- 0,(char *)NULL} ;
+ {
+ INT, "int",
+ NAME,"NAME",
+ PLUSEQ,"+=",
+ MINUSEQ,"-=",
+ MULTEQ,"*=",
+ DIVEQ,"/=",
+ LSHIFTEQ,"<<=",
+ RSHIFTEQ,">>=",
+ ANDEQ,"&=",
+ OREQ,"|=",
+ OROR,"||",
+ ANDAND,"&&",
+ EQ,"==",
+ NE,"!=",
+ LE,"<=",
+ GE,">=",
+ LSHIFT,"<<",
+ RSHIFT,">>=",
+ ALIGN_K,"ALIGN",
+ BLOCK,"BLOCK",
+ SECTIONS,"SECTIONS",
+ SIZEOF_HEADERS,"SIZEOF_HEADERS",
+ NEXT,"NEXT",
+ SIZEOF,"SIZEOF",
+ ADDR,"ADDR",
+ MEMORY,"MEMORY",
+
+
+
+
+
+ DEFINED,"DEFINED",
+ TARGET_K,"TARGET",
+ SEARCH_DIR,"SEARCH_DIR",
+ MAP,"MAP",
+ LONG,"LONG",
+ SHORT,"SHORT",
+ BYTE,"BYTE",
+ ENTRY,"ENTRY",
+ 0,(char *)NULL} ;
}
static void
-make_abs(ptr)
-etree_value_type *ptr;
+DEFUN(make_abs,(ptr),
+ etree_value_type *ptr)
{
if (ptr->section != (lang_output_section_statement_type *)NULL) {
asection *s = ptr->section->bfd_section;
}
}
+
static
-etree_value_type new_abs(value)
-bfd_vma value;
+DEFUN(etree_value_type new_abs,(value),
+ bfd_vma value)
{
etree_value_type new;
new.valid = true;
CONST char *op)
{
if (os == (lang_output_section_statement_type *)NULL) {
- info("%F%P %s uses undefined section %s\n", op, name);
+ einfo("%F%P %s uses undefined section %s\n", op, name);
}
if (os->processed == false) {
- info("%F%P %s forward reference of section %s\n",op, name);
+ einfo("%F%P %s forward reference of section %s\n",op, name);
}
}
-etree_type *exp_intop(value)
-bfd_vma value;
+etree_type *
+DEFUN(exp_intop,(value),
+ bfd_vma value)
{
- etree_type *new = (etree_type *)ldmalloc(sizeof(new->value));
+ etree_type *new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->value)));
new->type.node_code = INT;
new->value.value = value;
new->type.node_class = etree_value;
static
-etree_value_type new_rel(value, section)
-bfd_vma value;
-lang_output_section_statement_type *section;
+DEFUN(etree_value_type new_rel,(value, section),
+ bfd_vma value AND
+ lang_output_section_statement_type *section)
{
etree_value_type new;
new.valid = true;
}
static
-etree_value_type new_rel_from_section(value, section)
-bfd_vma value;
-lang_output_section_statement_type *section;
+DEFUN(etree_value_type
+ new_rel_from_section, (value, section),
+ bfd_vma value AND
+ lang_output_section_statement_type *section)
{
etree_value_type new;
new.valid = true;
}
static etree_value_type
-fold_binary(tree, current_section, allocation_done, dot, dotp)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type allocation_done;
-bfd_vma dot;
-bfd_vma *dotp;
+DEFUN(fold_binary,(tree, current_section, allocation_done, dot, dotp),
+ etree_type *tree AND
+ lang_output_section_statement_type *current_section AND
+ lang_phase_type allocation_done AND
+ bfd_vma dot AND
+ bfd_vma *dotp)
{
etree_value_type result;
/* Mod, both absolule*/
if (other.value == 0) {
- info("%F%S % by zero\n");
+ einfo("%F%S % by zero\n");
}
result.value %= other.value;
break;
case '/':
if (other.value == 0) {
- info("%F%S / by zero\n");
+ einfo("%F%S / by zero\n");
}
result.value /= other.value;
break;
}
return result;
}
-etree_value_type invalid()
+etree_value_type
+DEFUN_VOID(invalid)
{
etree_value_type new;
new.valid = false;
return new;
}
-etree_value_type fold_name(tree, current_section, allocation_done, dot)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type allocation_done;
-bfd_vma dot;
-
+etree_value_type
+DEFUN(fold_name, (tree, current_section, allocation_done, dot),
+ etree_type *tree AND
+ lang_output_section_statement_type *current_section AND
+ lang_phase_type allocation_done AND
+ bfd_vma dot)
{
etree_value_type result;
switch (tree->type.node_code)
}
}
if (result.valid == false) {
- info("%F%S: undefined symbol `%s' referenced in expression.\n",
+ einfo("%F%S: undefined symbol `%s' referenced in expression.\n",
tree->name.name);
}
lang_output_section_statement_type *os =
lang_output_section_find(tree->name.name);
check(os,tree->name.name,"SIZEOF");
- result = new_abs((bfd_vma)(os->bfd_section->size));
+ result = new_abs((bfd_vma)(os->bfd_section->_raw_size));
}
else {
result = invalid();
return result;
}
-etree_value_type exp_fold_tree(tree, current_section, allocation_done,
- dot, dotp)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type allocation_done;
-bfd_vma dot;
-bfd_vma *dotp;
+etree_value_type
+DEFUN(exp_fold_tree,(tree, current_section, allocation_done,
+ dot, dotp),
+ etree_type *tree AND
+ lang_output_section_statement_type *current_section AND
+ lang_phase_type allocation_done AND
+ bfd_vma dot AND
+ bfd_vma *dotp)
{
etree_value_type result;
if (tree == (etree_type *)NULL) {
- result.valid = false;
- }
+ result.valid = false;
+ }
else {
- switch (tree->type.node_class)
+ 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)
{
- 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 ALIGN_K:
- if (allocation_done != lang_first_phase_enum) {
- result = new_rel_from_section(ALIGN(dot,
- result.value) ,
- current_section);
+ 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:
- if (allocation_done ==lang_allocating_phase_enum) {
- make_abs(&result);
- result.value = ALIGN(dot, result.value);
- }
- else {
- /* Return next place aligned to value */
- result.valid = false;
- }
- break;
- default:
- FAIL();
- }
}
+ 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:
+ if (allocation_done ==lang_allocating_phase_enum) {
+ make_abs(&result);
+ result.value = ALIGN(dot, result.value);
+ }
+ else {
+ /* Return next place aligned to value */
+ 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(tree->trinary.cond,
+ current_section,
+ allocation_done, dot, dotp);
+ if (result.valid) {
result = exp_fold_tree(result.value ?
tree->trinary.lhs:tree->trinary.rhs,
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) {
+ 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 {
- if (current_section ==
- (lang_output_section_statement_type *)NULL) {
- info("%F%S assignment to location counter invalid outside of SECTION\n");
- }
- else {
- unsigned long nextdot =result.value +
- current_section->bfd_section->vma;
- if (nextdot < dot) {
- info("%F%S cannot move location counter backwards");
+ result = exp_fold_tree(tree->assign.src,
+ current_section,
+ lang_allocating_phase_enum, dot, dotp);
+ if (result.valid == false) {
+ einfo("%F%S invalid assignment to location counter\n");
}
- else {
- *dotp = nextdot;
+ else {
+ if (current_section ==
+ (lang_output_section_statement_type *)NULL) {
+ einfo("%F%S assignment to location counter invalid outside of SECTION\n");
+ }
+ else {
+ unsigned long nextdot =result.value +
+ current_section->bfd_section->vma;
+ if (nextdot < dot) {
+ einfo("%F%S cannot move location counter backwards");
+ }
+ else {
+ *dotp = nextdot;
+ }
+ }
}
- }
}
- }
}
- else {
+ else {
ldsym_type *sy = ldsym_get(tree->assign.dst);
/* If this symbol has just been created then we'll place it into
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) {
+ {
+ asymbol *def;
+ asymbol **def_ptr ;
+ /* Add this definition to script file */
+ if (sy->sdefs_chain)
+ {
+ def_ptr = sy->sdefs_chain;
+ def = *def_ptr;
+
+ }
+ else
+ {
+ def_ptr = (asymbol **)ldmalloc((bfd_size_type)(sizeof(asymbol **)));
+ 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;
}
- else {
+ else {
/* Force to absolute */
def->value += result.section->bfd_section->vma;
- def->section = (asection *)NULL;
- def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE;
+ def->section = &bfd_abs_section;
+ def->flags = BSF_GLOBAL | BSF_EXPORT ;
}
- }
- else {
- def->section = (asection *)NULL;
- def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE;
- }
+ }
+ else {
+ def->section = &bfd_abs_section;
+ def->flags = BSF_GLOBAL | BSF_EXPORT ;
+ }
- def->udata = (PTR)NULL;
- def->name = sy->name;
- Q_enter_global_ref(def_ptr);
- }
+ def->udata = (PTR)NULL;
+ def->name = sy->name;
+
+ if (sy->sdefs_chain == 0) 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:
+ einfo("%F%S Need more of these %d",tree->type.node_class );
- }
- }
+ }
+ }
return result;
}
-etree_value_type exp_fold_tree_no_dot(tree, current_section, allocation_done)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type allocation_done;
+etree_value_type
+DEFUN(exp_fold_tree_no_dot,(tree, current_section, allocation_done),
+ etree_type *tree AND
+ lang_output_section_statement_type *current_section AND
+ lang_phase_type allocation_done)
{
return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
0, (bfd_vma *)NULL);
}
etree_type *
-exp_binop(code, lhs, rhs)
-int code;
-etree_type *lhs;
-etree_type *rhs;
+DEFUN(exp_binop,(code, lhs, rhs),
+ int code AND
+ etree_type *lhs AND
+ etree_type *rhs)
{
etree_type value, *new;
etree_value_type r;
{
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc(sizeof(new->binary));
+ new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->binary)));
memcpy((char *)new, (char *)&value, sizeof(new->binary));
return new;
}
etree_type *
-exp_trinop(code, cond, lhs, rhs)
-int code;
-etree_type *cond;
-etree_type *lhs;
-etree_type *rhs;
+DEFUN(exp_trinop,(code, cond, lhs, rhs),
+ int code AND
+ etree_type *cond AND
+ etree_type *lhs AND
+ etree_type *rhs)
{
etree_type value, *new;
etree_value_type r;
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc(sizeof(new->trinary));
+ new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->trinary)));
memcpy((char *)new,(char *) &value, sizeof(new->trinary));
return new;
}
etree_type *
-exp_unop(code, child)
-int code;
-etree_type *child;
+DEFUN(exp_unop,(code, child),
+ int code AND
+ etree_type *child)
{
etree_type value, *new;
value.unary.type.node_code = code;
value.unary.child = child;
value.unary.type.node_class = etree_unary;
-r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
- lang_first_phase_enum);
-if (r.valid) {
+ r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
+ lang_first_phase_enum);
+ if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc(sizeof(new->unary));
+ new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->unary)));
memcpy((char *)new, (char *)&value, sizeof(new->unary));
return new;
}
etree_type *
-exp_nameop(code, name)
-int code;
-char *name;
+DEFUN(exp_nameop,(code, name),
+ int code AND
+ CONST char *name)
{
etree_type value, *new;
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc(sizeof(new->name));
+ new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->name)));
memcpy((char *)new, (char *)&value, sizeof(new->name));
return new;
etree_type *
-exp_assop(code, dst, src)
-int code;
-char *dst;
-etree_type *src;
+DEFUN(exp_assop,(code, dst, src),
+ int code AND
+ CONST char *dst AND
+ etree_type *src)
{
etree_type value, *new;
return exp_intop(result);
}
#endif
- new = (etree_type*)ldmalloc(sizeof(new->assign));
+ new = (etree_type*)ldmalloc((bfd_size_type)(sizeof(new->assign)));
memcpy((char *)new, (char *)&value, sizeof(new->assign));
return new;
}
void
-exp_print_tree(outfile, tree)
-FILE *outfile;
-etree_type *tree;
+DEFUN(exp_print_tree,(outfile, tree),
+ FILE *outfile AND
+ etree_type *tree)
{
switch (tree->type.node_class) {
case etree_value:
- fprintf(outfile,"0x%08lx",(bfd_vma)(tree->value.value));
+ print_address(tree->value.value);
return;
+
case etree_assign:
#if 0
if (tree->assign.dst->sdefs != (asymbol *)NULL){
bfd_vma
-exp_get_vma(tree, def, name, allocation_done)
-etree_type *tree;
-bfd_vma def;
-char *name;
-lang_phase_type allocation_done;
+DEFUN(exp_get_vma,(tree, def, name, allocation_done),
+ etree_type *tree AND
+ bfd_vma def AND
+ char *name AND
+ lang_phase_type allocation_done)
{
etree_value_type r;
(lang_output_section_statement_type *)NULL,
allocation_done);
if (r.valid == false && name) {
- info("%F%S Nonconstant expression for %s\n",name);
+ einfo("%F%S Nonconstant expression for %s\n",name);
}
return r.value;
}
}
int
-exp_get_value_int(tree,def,name, allocation_done)
-etree_type *tree;
-int def;
-char *name;
-lang_phase_type allocation_done;
+DEFUN(exp_get_value_int,(tree,def,name, allocation_done),
+ etree_type *tree AND
+ int def AND
+ char *name AND
+ lang_phase_type allocation_done)
{
return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
}
-%{
-/*
- * $Id$
- *
- *
-*/
+/* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
-/*
- This is a YACC grammer intended to parse a superset of the AT&T
- linker scripting languaue.
+This file is part of GNU ld.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
- Written by Steve Chamberlain steve@cygnus.com
-*/
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+%{
+/*
+ * $Id$
+ */
#define DONTDECLARE_MALLOC
extern unsigned int lineno;
extern boolean trace_files;
extern boolean write_map;
-
+extern boolean option_longmap;
boolean hex_mode;
strip_symbols_type strip_symbols=STRIP_NONE;
%token OPTION_format OPTION_F OPTION_u OPTION_Bstatic OPTION_N
%token <integer> SIZEOF NEXT ADDR
%token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
-%token OPTION_v OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT
-%token OPTION_n OPTION_r OPTION_o OPTION_b OPTION_R
+%token OPTION_v OPTION_V OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT
+%token OPTION_n OPTION_r OPTION_o OPTION_b OPTION_R OPTION_relax
%token <name> OPTION_l OPTION_L OPTION_T OPTION_Aarch OPTION_Tfile OPTION_Texp
%token OPTION_Ur
%token ORIGIN FILL OPTION_g
ldversion();
option_v = true;
}
+ | OPTION_V
+ {
+ ldversion();
+ option_v = true;
+ }
| OPTION_t {
trace_files = true;
}
| OPTION_M {
+ if (write_map) {
+ option_longmap = true;
+ }
write_map = true;
+
}
| OPTION_n {
config.magic_demand_paged = false;
- config.text_read_only = true;
}
| OPTION_N {
+ config.text_read_only = false;
config.magic_demand_paged = false;
}
| OPTION_s {
config.relocateable_output = true;
config.build_constructors = false;
config.magic_demand_paged = false;
+ config.text_read_only = false;
}
| OPTION_Ur {
config.relocateable_output = true;
config.build_constructors = true;
config.magic_demand_paged = false;
+ config.text_read_only = false;
}
| OPTION_o filename
{
| OPTION_d {
command_line.force_common_definition = true;
}
+
+ | OPTION_relax {
+ command_line.relax = true;
+ }
| OPTION_dc
{
command_line.force_common_definition = true;
#include "ldemul.h"
#include "ldlex.h"
#include "ldmisc.h"
+#include "ldindr.h"
+#include "ldctor.h"
/* FORWARDS */
PROTO(static void, print_statements,(void));
PROTO(static void, print_statement,(lang_statement_union_type *,
stuff to the data section without pain */
static lang_statement_list_type end_of_data_section_statement_list;
-/* List of statements needed to handle consxtructors */
-static lang_statement_list_type constructor_list;
+/* List of statements needed to handle constructors */
+extern lang_statement_list_type constructor_list;
static boolean placed_commons = false;
static lang_output_section_statement_type *default_common_section;
static section_userdata_type common_section_userdata;
static lang_statement_list_type statement_list;
/* EXPORTS */
+boolean relaxing;
lang_statement_list_type *stat_ptr = &statement_list;
lang_input_statement_type *script_file = 0;
statement_list.head);
}
/*----------------------------------------------------------------------*/
-static void
+void
DEFUN(lang_list_init,(list),
lang_statement_list_type *list)
{
DEFUN(init_os,(s),
lang_output_section_statement_type *s)
{
- section_userdata_type *new =
- (section_userdata_type *)
+ asection *section = bfd_get_section_by_name(output_bfd, s->name);
+ section_userdata_type *new =
+ (section_userdata_type *)
ldmalloc((bfd_size_type)(sizeof(section_userdata_type)));
s->bfd_section = bfd_get_section_by_name(output_bfd, s->name);
if (s->bfd_section == (asection *)NULL)
s->bfd_section = bfd_make_section(output_bfd, s->name);
if (s->bfd_section == (asection *)NULL) {
- info("%P%F output format %s cannot represent section called %s\n",
- output_bfd->xvec->name,
- s->name);
+ einfo("%P%F output format %s cannot represent section called %s\n",
+ output_bfd->xvec->name, s->name);
}
s->bfd_section->output_section = s->bfd_section;
/* s->bfd_section->flags = s->flags;*/
/* vma to allow us to output a section through itself */
s->bfd_section->output_offset = 0;
get_userdata( s->bfd_section) = (PTR)new;
+
}
/***********************************************************************
if (output == (bfd *)NULL)
{
if (bfd_error == invalid_target) {
- info("%P%F target %s not found\n", output_target);
+ einfo("%P%F target %s not found\n", output_target);
}
- info("%P%F problem opening output file %s, %E", name);
+ einfo("%P%F problem opening output file %s, %E", name);
}
- output->flags |= D_PAGED;
+/* output->flags |= D_PAGED;*/
bfd_set_format(output, bfd_object);
return output;
}
output_bfd = open_output(statement->output_statement.name);
ldemul_set_output_arch();
if (config.magic_demand_paged && !config.relocateable_output)
- output_bfd->flags |= ~D_PAGED;
+ output_bfd->flags |= D_PAGED;
else
output_bfd->flags &= ~D_PAGED;
if (config.text_read_only)
def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd);
*def_ptr= def;
def->name = ptr->name;
- def->flags = BSF_UNDEFINED;
- def->section = (asection *)NULL;
+ def->section = &bfd_und_section;
Q_enter_global_ref(def_ptr);
ptr = ptr->next;
}
(s->address_statement.section_name);
os->addr_tree = s->address_statement.address;
if (os->bfd_section == (asection *)NULL) {
- info("%P%F can't set the address of undefined section %s\n",
- s->address_statement.section_name);
+ einfo("%P%F can't set the address of undefined section %s\n",
+ s->address_statement.section_name);
}
}
break;
print_space();
print_address(section->vma);
print_space();
- print_size(section->size);
+ print_size(bfd_get_section_size_before_reloc(section));
print_space();
print_alignment(section->alignment_power);
print_space();
lang_input_section_type *in)
{
asection *i = in->section;
+ int size = i->flags & SEC_HAS_CONTENTS ?
+ bfd_get_section_size_after_reloc(i) :
+ bfd_get_section_size_before_reloc(i);
+
- if(i->size != 0) {
+ if(size != 0) {
print_section("");
printf(" ");
print_section(i->name);
if (i->output_section) {
print_address(i->output_section->vma + i->output_offset);
printf(" ");
- print_size(i->size);
+ print_size(size);
printf(" ");
print_alignment(i->alignment_power);
printf(" ");
}
- print_dot = outside_section_address(i) + i->size;
+ print_dot = outside_section_address(i) + size;
}
else {
printf("No output section allocated\n");
lang_statement_union_type *s AND
lang_output_section_statement_type *os)
{
- while (s) {
- switch (s->header.type) {
- case lang_constructors_statement_enum:
- printf("constructors:\n");
-print_statement(constructor_list.head, os);
-break;
-
- case lang_wild_statement_enum:
- print_wild_statement(&s->wild_statement, os);
- break;
- default:
- printf("Fail with %d\n",s->header.type);
- FAIL();
- break;
- case lang_address_statement_enum:
- printf("address\n");
- break;
- break;
- case lang_object_symbols_statement_enum:
- printf("object symbols\n");
- break;
- case lang_fill_statement_enum:
- print_fill_statement(&s->fill_statement);
- break;
- case lang_data_statement_enum:
- print_data_statement(&s->data_statement);
- break;
- case lang_input_section_enum:
- print_input_section(&s->input_section);
- break;
- case lang_padding_statement_enum:
- print_padding_statement(&s->padding_statement);
- break;
- case lang_output_section_statement_enum:
- print_output_section_statement(&s->output_section_statement);
- break;
- case lang_assignment_statement_enum:
- print_assignment(&s->assignment_statement,
- os);
- break;
-
-
- case lang_target_statement_enum:
- printf("TARGET(%s)\n", s->target_statement.target);
- break;
- case lang_output_statement_enum:
- printf("OUTPUT(%s %s)\n",
- s->output_statement.name,
- output_target);
- break;
- case lang_input_statement_enum:
- print_input_statement(&s->input_statement);
- break;
- case lang_afile_asection_pair_statement_enum:
- FAIL();
- break;
+ while (s)
+ {
+ switch (s->header.type)
+ {
+ case lang_constructors_statement_enum:
+ printf("constructors:\n");
+ print_statement(constructor_list.head, os);
+ break;
+ case lang_wild_statement_enum:
+ print_wild_statement(&s->wild_statement, os);
+ break;
+ default:
+ printf("Fail with %d\n",s->header.type);
+ FAIL();
+ break;
+ case lang_address_statement_enum:
+ printf("address\n");
+ break;
+ break;
+ case lang_object_symbols_statement_enum:
+ printf("object symbols\n");
+ break;
+ case lang_fill_statement_enum:
+ print_fill_statement(&s->fill_statement);
+ break;
+ case lang_data_statement_enum:
+ print_data_statement(&s->data_statement);
+ break;
+ case lang_input_section_enum:
+ print_input_section(&s->input_section);
+ break;
+ case lang_padding_statement_enum:
+ print_padding_statement(&s->padding_statement);
+ break;
+ case lang_output_section_statement_enum:
+ print_output_section_statement(&s->output_section_statement);
+ break;
+ case lang_assignment_statement_enum:
+ print_assignment(&s->assignment_statement,
+ os);
+ break;
+ case lang_target_statement_enum:
+ printf("TARGET(%s)\n", s->target_statement.target);
+ break;
+ case lang_output_statement_enum:
+ printf("OUTPUT(%s %s)\n",
+ s->output_statement.name,
+ output_target);
+ break;
+ case lang_input_statement_enum:
+ print_input_statement(&s->input_statement);
+ break;
+ case lang_afile_asection_pair_statement_enum:
+ FAIL();
+ break;
+ }
+ s = s->next;
}
- s = s->next;
- }
}
if (power > output_section_statement->alignment_power) {
output_section_statement->alignment_power = power;
}
- output_section_statement->size += alignment_needed;
+ output_section_statement->_raw_size += alignment_needed;
return alignment_needed + dot;
}
which we will actually allocate */
if (((i->flags &
(SEC_HAS_CONTENTS | SEC_LOAD)) == (SEC_HAS_CONTENTS | SEC_LOAD))
- && (i->size > largest_section)) {
- largest_section = i->size;
+ && (bfd_get_section_size_before_reloc(i) > largest_section)) {
+ largest_section = bfd_get_section_size_before_reloc(i);
}
/* Remember where in the output section this input section goes */
i->output_offset = dot - output_section_statement->bfd_section->vma;
/* Mark how big the output section must be to contain this now */
- dot += i->size;
- output_section_statement->bfd_section->size =
+ dot += bfd_get_section_size_before_reloc(i);
+output_section_statement->bfd_section->_raw_size =
dot - output_section_statement->bfd_section->vma;
}
else
return dot ;
}
-
+#if 0
/* Work out the size of the output sections
- from the sizes of the input sections */
+ from the sizes of the input sections */
static bfd_vma
-DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot),
+DEFUN(lang_size_sections,(s, output_section_statement, prev, fill,
+ dot),
lang_statement_union_type *s AND
lang_output_section_statement_type * output_section_statement AND
lang_statement_union_type **prev AND
unsigned short fill AND
bfd_vma dot)
+
{
/* Size up the sections from their constituent parts */
for (; s != (lang_statement_union_type *)NULL ; s = s->next)
lang_allocating_phase_enum,
dot, &dot);
if (r.valid == false) {
- info("%F%S: non constant address expression for section %s\n",
+ einfo("%F%S: non constant address expression for section %s\n",
os->name);
}
dot = r.value;
case lang_data_statement_enum:
{
- unsigned int size;
+ unsigned int size = 0;
s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma;
s->data_statement.output_section =
output_section_statement->bfd_section;
prev = &s->header.next;
}
return dot;
+}
+#else
+/* Sizing happens in two passes, first pass we allocate worst case
+ stuff. The second pass (if relaxing), we use what we learnt to
+ change the size of some relocs from worst case to better
+ */
+static boolean had_relax;
+
+static bfd_vma
+DEFUN(lang_size_sections,(s, output_section_statement, prev, fill,
+ dot, relax),
+ lang_statement_union_type *s AND
+ lang_output_section_statement_type * output_section_statement AND
+ lang_statement_union_type **prev AND
+ unsigned short fill AND
+ bfd_vma dot AND
+ boolean relax)
+{
+ /* Size up the sections from their constituent parts */
+ for (; s != (lang_statement_union_type *)NULL ; s = s->next)
+ {
+ switch (s->header.type) {
+
+ case lang_output_section_statement_enum:
+ {
+ bfd_vma after;
+ lang_output_section_statement_type *os =
+ &(s->output_section_statement);
+ /* The start of a section */
+
+ if (os->addr_tree == (etree_type *)NULL) {
+ /* No address specified for this section, get one
+ from the region specification
+ */
+ if (os->region == (lang_memory_region_type *)NULL) {
+ os->region = lang_memory_region_lookup("*default*");
+ }
+ dot = os->region->current;
+ }
+ else {
+ etree_value_type r ;
+ r = exp_fold_tree(os->addr_tree,
+ (lang_output_section_statement_type *)NULL,
+ lang_allocating_phase_enum,
+ dot, &dot);
+ if (r.valid == false) {
+ einfo("%F%S: non constant address expression for section %s\n",
+ os->name);
+ }
+ dot = r.value;
+ }
+ /* The section starts here */
+ /* First, align to what the section needs */
+
+ dot = align_power(dot, os->bfd_section->alignment_power);
+ os->bfd_section->vma = dot;
+ os->bfd_section->output_offset = 0;
+
+ (void) lang_size_sections(os->children.head, os, &os->children.head,
+ os->fill, dot, relax);
+ /* Ignore the size of the input sections, use the vma and size to */
+ /* align against */
+
+
+ after = ALIGN(os->bfd_section->vma +
+ os->bfd_section->_raw_size,
+ os->block_value) ;
+
+
+ os->bfd_section->_raw_size = after - os->bfd_section->vma;
+ dot = os->bfd_section->vma + os->bfd_section->_raw_size;
+ os->processed = true;
+
+ /* Replace into region ? */
+ if (os->addr_tree == (etree_type *)NULL
+ && os->region !=(lang_memory_region_type*)NULL ) {
+ os->region->current = dot;
+ }
+ }
+
+ break;
+ case lang_constructors_statement_enum:
+ dot = lang_size_sections(constructor_list.head,
+ output_section_statement,
+ &s->wild_statement.children.head,
+ fill,
+ dot, relax);
+ break;
+
+ case lang_data_statement_enum:
+ {
+ unsigned int size = 0;
+ s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma;
+ s->data_statement.output_section =
+ output_section_statement->bfd_section;
+
+ switch (s->data_statement.type) {
+ case LONG:
+ size = LONG_SIZE;
+ break;
+ case SHORT:
+ size = SHORT_SIZE;
+ break;
+ case BYTE:
+ size = BYTE_SIZE;
+ break;
+
+ }
+ dot += size;
+ output_section_statement->bfd_section->_raw_size += size;
+ }
+ break;
+
+ case lang_wild_statement_enum:
+
+ dot = lang_size_sections(s->wild_statement.children.head,
+ output_section_statement,
+ &s->wild_statement.children.head,
+
+ fill, dot, relax);
+
+ break;
+
+ case lang_object_symbols_statement_enum:
+ create_object_symbols = output_section_statement;
+ break;
+ case lang_output_statement_enum:
+ case lang_target_statement_enum:
+ break;
+ case lang_input_section_enum:
+if (relax)
+{
+ relaxing = true;
+
+
+had_relax |= relax_section(prev);
+ relaxing = false;
+
}
+ dot = size_input_section(prev,
+ output_section_statement,
+ output_section_statement->fill, dot);
+ break;
+ case lang_input_statement_enum:
+ break;
+ case lang_fill_statement_enum:
+ fill = s->fill_statement.fill;
+ break;
+ case lang_assignment_statement_enum:
+ {
+ bfd_vma newdot = dot;
+ exp_fold_tree(s->assignment_statement.exp,
+ output_section_statement,
+ lang_allocating_phase_enum,
+ dot,
+ &newdot);
+
+ if (newdot != dot)
+ /* We've been moved ! so insert a pad */
+ {
+ lang_statement_union_type *new =
+ (lang_statement_union_type *)
+ ldmalloc((bfd_size_type)(sizeof(lang_padding_statement_type)));
+ /* Link into existing chain */
+ new->header.next = *prev;
+ *prev = new;
+ new->header.type = lang_padding_statement_enum;
+ new->padding_statement.output_section =
+ output_section_statement->bfd_section;
+ new->padding_statement.output_offset =
+ dot - output_section_statement->bfd_section->vma;
+ new->padding_statement.fill = fill;
+ new->padding_statement.size = newdot - dot;
+ output_section_statement->bfd_section->_raw_size +=
+ new->padding_statement.size;
+ dot = newdot;
+ }
+ }
+
+ break;
+ default:
+ FAIL();
+ break;
+/* This can only get here when relaxing is turned on */
+ case lang_padding_statement_enum:
+
+ case lang_address_statement_enum:
+ break;
+ }
+ prev = &s->header.next;
+ }
+ return dot;
+}
+#endif
static bfd_vma
DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot),
&(s->output_section_statement);
dot = os->bfd_section->vma;
(void) lang_do_assignments(os->children.head, os, os->fill, dot);
- dot = os->bfd_section->vma + os->bfd_section->size;
+ dot = os->bfd_section->vma + os->bfd_section->_raw_size;
}
break;
case lang_wild_statement_enum:
value = exp_fold_tree(s->data_statement.exp,
0, lang_final_phase_enum, dot, &dot);
s->data_statement.value = value.value;
- if (value.valid == false) info("%F%P: Invalid data statement\n");
+ if (value.valid == false) einfo("%F%P: Invalid data statement\n");
}
switch (s->data_statement.type) {
case LONG:
case lang_input_section_enum:
{
asection *in = s->input_section.section;
- dot += in->size;
+ dot += bfd_get_section_size_before_reloc(in);
}
break;
((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);
+
+ com->section->_raw_size =
+ ALIGN(com->section->_raw_size, align);
/* Remember if this is the biggest alignment ever seen */
if (power_of_two > com->section->alignment_power) {
we remember that it was common once. */
com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON;
- com->value = com->section->size;
+ com->value = com->section->_raw_size;
if (write_map)
{
com->the_bfd->filename);
}
- com->section->size += size;
+ com->section->_raw_size += size;
}
}
/* ptr->flag_loadable= state;*/
break;
default:
- info("%P%F illegal syntax in flags\n");
+ einfo("%P%F illegal syntax in flags\n");
break;
}
flags++;
+/* Reset the current counters in the regions */
+static void
+ DEFUN_VOID(reset_memory_regions)
+{
+ lang_memory_region_type *p = lang_memory_region_list;
+ for (p = lang_memory_region_list;
+ p != ( lang_memory_region_type *)NULL;
+ p = p->next)
+ {
+ p->current = p->origin;
+ }
+}
asymbol *
return def;
}
-/* run through the symbol table, find all the symbols which are
- constructors and for each one, create statements to do something
- like..
-
- for
- __CTOR_LIST__, foo
-
- __CTOR_LIST__ = . ;
- LONG(__CTOR_LIST_END - . / 4 - 2)
- *(foo)
- __CTOR_LIST_END= .
-
- Put these statements onto a special list.
-
-*/
-
-typedef struct constructor_list
-{
-ldsym_type *sym;
- struct constructor_list *next;
-} constructor_list_type;
-
-static constructor_list_type *constructor_name_list;
-
-void
-DEFUN(ldlang_add_constructor,(name),
-ldsym_type *name)
-{
-
- constructor_list_type *next = constructor_name_list;
-
- if (name->flags & SYM_CONSTRUCTOR) return;
-
- next = (constructor_list_type *) ldmalloc(sizeof(constructor_list_type));
- next->next= constructor_name_list;
- next->sym= name;
- name->flags |= SYM_CONSTRUCTOR;
- constructor_name_list = next;
-
-}
-
-void
-DEFUN_VOID(find_constructors)
-{
- lang_statement_list_type *old = stat_ptr;
- constructor_list_type *p = constructor_name_list;
- stat_ptr = & constructor_list;
- lang_list_init(stat_ptr);
- while (p != (constructor_list_type *)NULL)
- {
- /* Have we already done this one ? */
- CONST char *name = p->sym->name;
- int len = strlen(name);
- char *end = ldmalloc(len+3);
- strcpy(end, name);
- strcat(end,"$e");
-
- lang_add_assignment
- ( exp_assop('=',name, exp_nameop(NAME,".")));
-
- lang_add_data
- (LONG, exp_binop('-',
- exp_binop ( '/',
- exp_binop ( '-',
- exp_nameop(NAME, end),
- exp_nameop(NAME,".")),
- exp_intop(4)),
-
- exp_intop(2)));
-
-
- lang_add_wild(name, (char *)NULL);
- lang_add_data(LONG, exp_intop(0));
- lang_add_assignment
- (exp_assop('=', end, exp_nameop(NAME,".")));
-p = p->next;
- }
-
-
- stat_ptr = old;
-}
void
DEFUN_VOID(lang_process)
{
if (had_script == false) {
- parse_line(ldemul_get_script());
- }
+ parse_line(ldemul_get_script());
+ }
lang_reasonable_defaults();
current_target = default_target;
ldemul_before_allocation();
+
/* Size up the sections */
lang_size_sections(statement_list.head,
(lang_output_section_statement_type *)NULL,
- &(statement_list.head), 0, (bfd_vma)0);
+ &(statement_list.head), 0, (bfd_vma)0, false);
+
+
+ /* Move the global symbols around */
+ lang_relocate_globals();
+
+ /* Now run around and relax if we can */
+ if (command_line.relax)
+ {
+ reset_memory_regions();
+
+ had_relax = true;
+ while (had_relax)
+ {
+
+ had_relax = false;
+
+ lang_size_sections(statement_list.head,
+ (lang_output_section_statement_type *)NULL,
+ &(statement_list.head), 0, (bfd_vma)0, true);
+ /* FIXME. Until the code in relax is fixed so that it only reads in
+ stuff once, we cant iterate since there is no way for the linker to
+ know what has been patched and what hasn't */
+ break;
+
+ }
+
+
+
+
+ }
+
/* See if anything special should be done now we know how big
everything is */
(lang_output_section_statement_type *)NULL,
0, (bfd_vma)0);
+
/* Make sure that we're not mixing architectures */
lang_check();
- /* Move the global symbols around */
- lang_relocate_globals();
-
/* Final stuffs */
lang_finish();
}
CONST char *name)
{
if (startup_file != (char *)NULL) {
- info("%P%FMultiple STARTUP files\n");
+ einfo("%P%FMultiple STARTUP files\n");
}
first_file->filename = name;
first_file->local_sym_name = name;
if (ldsym_undefined(name)) {
asection *s = bfd_get_section_by_name(output_bfd, section);
asymbol *def = create_symbol(name,
- BSF_GLOBAL | BSF_EXPORT |
- BSF_ABSOLUTE,
- (asection *)NULL);
+ BSF_GLOBAL | BSF_EXPORT ,
+ &bfd_abs_section);
+
+
if (s != (asection *)NULL) {
def->value = s->vma;
}
asection *s = bfd_get_section_by_name(output_bfd, section);
/* Add a symbol called _end */
asymbol *def = create_symbol(name,
- BSF_GLOBAL | BSF_EXPORT |
- BSF_ABSOLUTE,
- (asection *)NULL);
+ BSF_GLOBAL | BSF_EXPORT ,
+ &bfd_abs_section);
+
if (s != (asection *)NULL) {
- def->value = s->vma + s->size;
+ def->value = s->vma + s->_raw_size;
}
else {
def->value = 0;
/* ldlang.h -
-
+
Copyright (C) 1991 Free Software Foundation, Inc.
-
+
This file is part of GLD, the Gnu Linker.
-
+
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
-
+
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
lang_input_file_is_symbols_only_enum,
lang_input_file_is_marker_enum,
lang_input_file_is_fake_enum,
-lang_input_file_is_search_file_enum,
+ lang_input_file_is_search_file_enum,
lang_input_file_is_file_enum } lang_input_file_enum_type;
typedef unsigned short fill_type;
} lang_statement_list_type;
-typedef struct {
- boolean flag_read;
- boolean flag_write;
- boolean flag_executable;
- boolean flag_loadable;
-} lang_section_flags_type;
+
typedef struct memory_region_struct {
char *name;
bfd_vma origin;
bfd_offset length;
bfd_vma current;
- lang_section_flags_type flags;
+ int flags;
} lang_memory_region_type ;
typedef struct lang_statement_header_struct
-{
-union lang_statement_union *next;
- enum statement_enum {
- lang_output_section_statement_enum,
- lang_assignment_statement_enum,
- lang_input_statement_enum,
- lang_address_statement_enum,
- lang_wild_statement_enum,
- lang_input_section_enum,
- lang_object_symbols_statement_enum,
- lang_fill_statement_enum,
- lang_data_statement_enum,
- lang_target_statement_enum,
- lang_output_statement_enum,
- lang_padding_statement_enum,
-
- lang_afile_asection_pair_statement_enum
- } type;
-
-} lang_statement_header_type;
+ {
+ union lang_statement_union *next;
+ enum statement_enum {
+ lang_output_section_statement_enum,
+ lang_assignment_statement_enum,
+ lang_input_statement_enum,
+ lang_address_statement_enum,
+ lang_wild_statement_enum,
+ lang_input_section_enum,
+ lang_object_symbols_statement_enum,
+ lang_fill_statement_enum,
+ lang_data_statement_enum,
+ lang_target_statement_enum,
+ lang_output_statement_enum,
+ lang_padding_statement_enum,
+
+ lang_afile_asection_pair_statement_enum,
+ lang_constructors_statement_enum
+ } type;
+
+ } lang_statement_header_type;
typedef struct
-{
- lang_statement_header_type header;
- union etree_union *exp;
-} lang_assignment_statement_type;
+ {
+ lang_statement_header_type header;
+ union etree_union *exp;
+ } lang_assignment_statement_type;
typedef struct lang_target_statement_struct {
typedef struct lang_output_section_statement_struct
-{
- lang_statement_header_type header;
- union etree_union *addr_tree;
- lang_statement_list_type children;
- CONST char *memspec;
- union lang_statement_union *next;
- CONST char *name;
- unsigned long subsection_alignment;
- boolean processed;
-
- asection *bfd_section;
- lang_section_flags_type flags;
- struct memory_region_struct *region;
- size_t block_value;
- fill_type fill;
-} lang_output_section_statement_type;
+ {
+ lang_statement_header_type header;
+ union etree_union *addr_tree;
+ lang_statement_list_type children;
+ CONST char *memspec;
+ union lang_statement_union *next;
+ CONST char *name;
+ unsigned long subsection_alignment;
+ boolean processed;
+
+ asection *bfd_section;
+ int flags;
+ struct memory_region_struct *region;
+ size_t block_value;
+ fill_type fill;
+ } lang_output_section_statement_type;
typedef struct {
/* Usually the same as filename, but for a file spec'd with -l
this is the -l switch itself rather than the filename. */
CONST char *local_sym_name;
-
- /* Describe the layout of the contents of the file */
-
- /* The file's a.out header. */
- /* struct exec header;*/
- /* Offset in file of GDB symbol segment, or 0 if there is none. */
- int symseg_offset;
-
- /* Describe data from the file loaded into core */
-
+
bfd *the_bfd;
-
+
boolean closed;
file_ptr passive_position;
-
+
/* Symbol table of the file. */
asymbol **asymbols;
unsigned int symbol_count;
-
+
/* For library members only */
-
+
/* For a library, points to chain of entries for the library members. */
struct lang_input_statement_struct *subfiles;
/* For a library member, offset of the member within the archive.
Zero for files that are not library members. */
/* int starting_offset;*/
/* Size of contents of this file, if library member. */
- int total_size;
+ bfd_size_type total_size;
/* For library member, points to the library's own entry. */
struct lang_input_statement_struct *superfile;
/* For library member, points to next entry for next member. */
struct lang_input_statement_struct *chain;
/* Point to the next file - whatever it is, wanders up and down
archives */
-
+
union lang_statement_union *next;
/* Point to the next file, but skips archive contents */
union lang_statement_union *next_real_file;
-
+
boolean is_archive;
-
+
/* 1 means search a set of directories for this file. */
boolean search_dirs_flag;
-
+
/* 1 means this is base file of incremental load.
Do not load this file's text or data.
Also default text_start to after this file's bss. */
-
+
boolean just_syms_flag;
-
+
boolean loaded;
-
-
+
+
/* unsigned int globals_in_this_file;*/
CONST char *target;
boolean real;
-
+
asection *common_section;
asection *common_output_section;
} lang_input_statement_type;
lang_statement_header_type header;
asection *section;
lang_input_statement_type *ifile;
-
+
} lang_input_section_type;
typedef struct lang_wild_statement_struct {
lang_statement_header_type header;
-CONST char *section_name;
-CONST char *filename;
+ CONST char *section_name;
+ CONST char *filename;
lang_statement_list_type children;
} lang_wild_statement_type;
} lang_padding_statement_type;
typedef union lang_statement_union
-{
- lang_statement_header_type header;
- union lang_statement_union *next;
- lang_wild_statement_type wild_statement;
- lang_data_statement_type data_statement;
- lang_address_statement_type address_statement;
- lang_output_section_statement_type output_section_statement;
- lang_afile_asection_pair_statement_type afile_asection_pair_statement;
- lang_assignment_statement_type assignment_statement;
- lang_input_statement_type input_statement;
- lang_target_statement_type target_statement;
- lang_output_statement_type output_statement;
- lang_input_section_type input_section;
- lang_common_statement_type common_statement;
- lang_object_symbols_statement_type object_symbols_statement;
- lang_fill_statement_type fill_statement;
- lang_padding_statement_type padding_statement;
-} lang_statement_union_type;
+ {
+ lang_statement_header_type header;
+ union lang_statement_union *next;
+ lang_wild_statement_type wild_statement;
+ lang_data_statement_type data_statement;
+ lang_address_statement_type address_statement;
+ lang_output_section_statement_type output_section_statement;
+ lang_afile_asection_pair_statement_type afile_asection_pair_statement;
+ lang_assignment_statement_type assignment_statement;
+ lang_input_statement_type input_statement;
+ lang_target_statement_type target_statement;
+ lang_output_statement_type output_statement;
+ lang_input_section_type input_section;
+ lang_common_statement_type common_statement;
+ lang_object_symbols_statement_type object_symbols_statement;
+ lang_fill_statement_type fill_statement;
+ lang_padding_statement_type padding_statement;
+ } lang_statement_union_type;
PROTO(void ,lang_map,(FILE *));
-PROTO(void,lang_set_flags,(lang_section_flags_type *, CONST char *));
+PROTO(void,lang_set_flags,(int *, CONST char *));
PROTO(void,lang_add_output,(CONST char *));
PROTO(void,lang_final,(void));
PROTO(void,lang_add_assignment,(union etree_union *));
PROTO(void,lang_add_attribute,(enum statement_enum));
PROTO(void,lang_startup,(CONST char *));
-PROTO(void,lang_float,(enum boolean));
+PROTO(void,lang_float,(enum bfd_boolean));
PROTO(void,lang_leave_output_section_statement,(bfd_vma, CONST char *));
PROTO(void,lang_abs_symbol_at_end_of,(CONST char *, CONST char *));
PROTO(void,lang_abs_symbol_at_beginning_of,(CONST char *, CONST char *));
PROTO(void,lang_statement_append,(struct statement_list *, union lang_statement_union *, union lang_statement_union **));
PROTO(void, lang_for_each_file,(void (*dothis)(lang_input_statement_type *)));
-
+
#define LANG_FOR_EACH_INPUT_STATEMENT(statement) \
extern lang_statement_list_type file_chain; \
lang_input_statement_type *statement; \
for (statement = (lang_input_statement_type *)file_chain.head;\
statement != (lang_input_statement_type *)NULL; \
statement = (lang_input_statement_type *)statement->next)\
-
+
#define LANG_FOR_EACH_INPUT_SECTION(statement, abfd, section, x) \
-{ extern lang_statement_list_type file_chain; \
- lang_input_statement_type *statement; \
- for (statement = (lang_input_statement_type *)file_chain.head;\
- statement != (lang_input_statement_type *)NULL; \
- statement = (lang_input_statement_type *)statement->next)\
- { \
- asection *section; \
- bfd *abfd = statement->the_bfd; \
+ { extern lang_statement_list_type file_chain; \
+ lang_input_statement_type *statement; \
+ for (statement = (lang_input_statement_type *)file_chain.head;\
+ statement != (lang_input_statement_type *)NULL; \
+ statement = (lang_input_statement_type *)statement->next)\
+ { \
+ asection *section; \
+ bfd *abfd = statement->the_bfd; \
for (section = abfd->sections; \
section != (asection *)NULL; \
section = section->next) { \
- x; \
- } \
- } \
+ x; \
+ } \
+ } \
}
#define LANG_FOR_EACH_OUTPUT_SECTION(section, x) \
- { extern bfd *output_bfd; \
- asection *section; \
- for (section = output_bfd->sections; \
- section != (asection *)NULL; \
- section = section->next) \
- { x; } \
- }
-
+ { extern bfd *output_bfd; \
+ asection *section; \
+ for (section = output_bfd->sections; \
+ section != (asection *)NULL; \
+ section = section->next) \
+ { x; } \
+ }
+
PROTO(void, lang_process,(void));
PROTO(void, ldlang_add_file,(lang_input_statement_type *));
*,lang_output_section_find,(CONST char * CONST));
PROTO(lang_input_statement_type *,
- lang_add_input_file,(char *name,
- lang_input_file_enum_type file_type,
- char *target));
+ lang_add_input_file,(char *name,
+ lang_input_file_enum_type file_type,
+ char *target));
PROTO(lang_output_section_statement_type *,
-lang_output_section_statement_lookup,(CONST char * CONST name));
+ lang_output_section_statement_lookup,(CONST char * CONST name));
PROTO(void, ldlang_add_undef,(CONST char *CONST name));
PROTO(void, lang_add_output_format,(CONST char *));
+
+
+void EXFUN(lang_list_init,( lang_statement_list_type*));
+
+void EXFUN(lang_add_data,(int type, union etree_union *));
#include "ldemul.h"
#include "ldlex.h"
#include "ldfile.h"
-
+#include "ldindr.h"
+#include "ldwarn.h"
+#include "ldctor.h"
/* IMPORTS */
extern boolean lang_has_input_file;
extern boolean trace_files;
*/
unsigned int total_files_seen;
+
/* IMPORTS */
args_type command_line;
ld_config_type config;
unix_relocate = 0;
command_line.force_common_definition = false;
+ init_bfd_error_vector();
+
ldfile_add_arch("");
ldfile_add_library_path("./");
config.make_executable = true;
info("%P: mode %s\n", emulation);
}
if (lang_has_input_file == false) {
- info("%P%F: No input files\n");
+ einfo("%P%F: No input files\n");
}
ldemul_after_parse();
/* Print error messages for any missing symbols, for any warning
symbols, and possibly multiple definitions */
- /* Print a map, if requested. */
-
- if (write_map) {
- ldsym_print_symbol_table ();
- lang_map(stdout);
- }
if (config.text_read_only) {
/* Look for a text section and mark the readonly attribute in it */
asection *found = bfd_get_section_by_name(output_bfd, ".text");
if (found == (asection *)NULL) {
- info("%P%F: text marked read only, but no text section present");
+ einfo("%P%F: text marked read only, but no text section present");
}
found->flags |= SEC_READONLY;
}
if (config.relocateable_output) {
output_bfd->flags &= ~EXEC_P;
- ldwrite();
+
+ ldwrite(write_map);
bfd_close(output_bfd);
}
else {
output_bfd->flags |= EXEC_P;
- ldwrite();
- bfd_close(output_bfd);
- if (config.make_executable == false && force_make_executable == false) {
+ ldwrite(write_map);
+
+ if (config.make_executable == false && force_make_executable ==false) {
+
unlink(output_filename);
}
+ else { bfd_close(output_bfd); };
return (!config.make_executable);
}
{
asymbol *sym = *nlist_p;
sym->value = 0;
- sym->flags = BSF_UNDEFINED;
- sym->section = (asection *)NULL;
+ sym->flags = 0;
+ sym->section = &bfd_und_section;
sym->udata =(PTR)( sp->srefs_chain);
sp->srefs_chain = nlist_p;
}
definitions seen, undefined global symbols and pending commons.
*/
+extern boolean relaxing;
void
Q_enter_global_ref (nlist_p)
}
else {
- if (flag_is_common(this_symbol_flags)) {
+ if (sym->section == &bfd_com_section) {
/* If we have a definition of this symbol already then
this common turns into a reference. Also we only
ever point to the largest common, so if we
}
}
- else if (flag_is_defined(this_symbol_flags)) {
+ else if (sym->section != &bfd_und_section) {
/* This is the definition of a symbol, add to def chain */
if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section) {
/* Multiple definition */
asymbol ** stat_symbols = stat ? stat->asymbols:0;
multiple_def_count++;
- info("%C: multiple definition of `%T'\n",
- sym->the_bfd,
- sym->section,
- stat1_symbols,
- sym->value,
- sym);
+ einfo("%C: multiple definition of `%T'\n",
+ sym->the_bfd, sym->section, stat1_symbols, sym->value, sym);
- info("%C: first seen here\n",
- sy->the_bfd,
- sy->section,
- stat_symbols,
- sy->value);
+ einfo("%C: first seen here\n",
+ sy->the_bfd, sy->section, stat_symbols, sy->value);
}
else {
sym->udata =(PTR)( sp->sdefs_chain);
sp->scoms_chain = 0;
commons_pending--;
}
- else if (sp->srefs_chain) {
+ else if (sp->srefs_chain && relaxing == false) {
/* If previously was undefined, then remember as defined */
undefined_global_sym_count--;
}
lang_input_statement_type *entry;
{
asymbol **q ;
+
entry->common_section =
- bfd_make_section(entry->the_bfd, "COMMON");
+ bfd_make_section_old_way(entry->the_bfd, "COMMON");
ldlang_add_file(entry);
{
asymbol *p = *q;
- if (flag_is_undefined_or_global_or_common_or_constructor(p->flags))
+ if (p->section == &bfd_und_section
+ || (p->flags & BSF_GLOBAL)
+ || p->section == &bfd_com_section
+ || (p->flags & BSF_CONSTRUCTOR))
{
Q_enter_global_ref(q);
}
if (p->flags & BSF_WARNING) {
add_warning(p);
}
- ASSERT(p->flags != 0);
+
}
}
}
else
{
- info("%F%B: malformed input file (not rel or archive) \n",
- entry->the_bfd);
+ einfo("%F%B: malformed input file (not rel or archive) \n",
+ entry->the_bfd);
}
}
}
if (archive_member_lang_input_statement_struct == 0) {
- info ("%F%I contains invalid archive member %s\n",
- entry,
- sp->name);
+ einfo ("%F%I contains invalid archive member %s\n",
+ entry, sp->name);
}
if (archive_member_lang_input_statement_struct->loaded == false)
add_indirect(q);
}
- if (p->flags & BSF_FORT_COMM
+ if (p->section == &bfd_com_section
|| p->flags & BSF_GLOBAL)
{
register ldsym_type *sp = ldsym_get_soft (p->name);
/* This is a symbol we are looking for. It is either
not yet defined or common. */
- if (flag_is_common(p->flags))
+ if (p->section == &bfd_com_section)
{
/* If the symbol in the table is a constructor, we won't to
(asymbol **)((*(sp->srefs_chain))->udata);
(*(sp->scoms_chain))->udata = (PTR)NULL;
- (*( sp->scoms_chain))->flags = BSF_FORT_COMM;
+ (*( sp->scoms_chain))->section =
+ &bfd_com_section;
+ (*( sp->scoms_chain))->flags = 0;
/* Remember the size of this item */
sp->scoms_chain[0]->value = p->value;
commons_pending++;
(asection *)NULL) {
((lang_input_statement_type *)
(com->the_bfd->usrdata))->common_section =
- bfd_make_section(com->the_bfd, "COMMON");
+ bfd_make_section_old_way(com->the_bfd, "COMMON");
}
}
}
return false;
}
+
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* ldmisc.c
+ Copyright (C) 1991 Free Software Foundation, Inc.
+
+ Written by Steve Chamberlain of Cygnus Support.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
- * $Id$
- */
+$Id$
-/*
- ldmisc.c
-*/
+ */
+#include "bfd.h"
#include "sysdep.h"
#include <varargs.h>
-#include "bfd.h"
#include "ld.h"
#include "ldmisc.h"
yyerror(arg)
char *arg;
{
- info("%P%F: %S %s\n",arg);
+ einfo("%P%F: %S %s\n",arg);
}
extern int errno;
%X no object output, fail return
%V hex bfd_vma
%C Clever filename:linenumber
+ %R info about a relent
%
*/
-void info(va_alist)
-va_dcl
+static void
+vfinfo(fp, fmt, arg)
+ FILE *fp;
+ char *fmt;
+ va_list arg;
{
- char *fmt;
boolean fatal = false;
- va_list arg;
- va_start(arg);
- fmt = va_arg(arg, char *);
while (*fmt) {
while (*fmt != '%' && *fmt != '\0') {
- fputc(*fmt, stderr);
+ putc(*fmt, fp);
fmt++;
}
if (*fmt == '%') {
config.make_executable = false;
break;
case 'V':
- fprintf(stderr,"%08lx", va_arg(arg, bfd_vma));
+ {
+ bfd_vma value = va_arg(arg, bfd_vma);
+ fprintf_vma(fp, value);
+ }
break;
case 'T':
{
asymbol *symbol = va_arg(arg, asymbol *);
- if (symbol) {
+ if (symbol)
+ {
asection *section = symbol->section;
- if ((symbol->flags & BSF_UNDEFINED) == 0) {
- CONST char *section_name = section == (asection *)NULL ?
- "absolute" : section->name;
- fprintf(stderr,"%s (%s)", symbol->name, section_name);
- }
- else {
- fprintf(stderr,"%s", symbol->name);
- }
+ CONST char *section_name = section->name;
+ fprintf(fp,"%s (%s)", symbol->name, section_name);
}
- else {
- fprintf(stderr,"no symbol");
+ else
+ {
+ fprintf(fp,"no symbol");
}
}
break;
{
bfd *abfd = va_arg(arg, bfd *);
if (abfd->my_archive) {
- fprintf(stderr,"%s(%s)", abfd->my_archive->filename,
+ fprintf(fp,"%s(%s)", abfd->my_archive->filename,
abfd->filename);
}
else {
- fprintf(stderr,"%s", abfd->filename);
+ fprintf(fp,"%s", abfd->filename);
}
}
fatal = true;
break;
case 'P':
- fprintf(stderr,"%s", program_name);
+ fprintf(fp,"%s", program_name);
break;
case 'E':
/* Replace with the most recent errno explanation */
- fprintf(stderr, bfd_errmsg(bfd_error));
+ fprintf(fp, bfd_errmsg(bfd_error));
break;
lang_input_statement_type *i =
va_arg(arg,lang_input_statement_type *);
- fprintf(stderr,"%s", i->local_sym_name);
+ fprintf(fp,"%s", i->local_sym_name);
}
break;
case 'S':
if (ldlex_input_stack) {
extern unsigned int lineno;
if (ldfile_input_filename == (char *)NULL) {
- fprintf(stderr,"command line");
+ fprintf(fp,"command line");
}
else {
- fprintf(stderr,"%s:%u", ldfile_input_filename, lineno );
+ fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
}
}
else {
int ch;
int n = 0;
- fprintf(stderr,"command (just before \"");
+ fprintf(fp,"command (just before \"");
ch = lex_input();
while (ch != 0 && n < 10) {
- fprintf(stderr, "%c", ch);
+ fprintf(fp, "%c", ch);
ch = lex_input();
n++;
}
- fprintf(stderr,"\")");
+ fprintf(fp,"\")");
}
break;
+
+ case 'R':
+ /* Print all that's interesting about a relent */
+ {
+ arelent *relent = va_arg(arg, arelent *);
+
+ fprintf(fp,"%s+0x%x (type %s)",
+ (*(relent->sym_ptr_ptr))->name,
+ relent->addend,
+ relent->howto->name);
+
+
+ }
+ break;
+
+
+
+
case 'C':
{
CONST char *filename;
if (filename == (char *)NULL)
filename = abfd->filename;
if (functionname != (char *)NULL)
- fprintf(stderr,"%s:%u: (%s)", filename, linenumber, functionname);
+ fprintf(fp,"%s:%u: (%s)", filename, linenumber, functionname);
else if (linenumber != 0)
- fprintf(stderr,"%s:%u", filename, linenumber);
+ fprintf(fp,"%s:%u", filename, linenumber);
else
- fprintf(stderr,"%s", filename);
+ fprintf(fp,"%s(%s+%0x)", filename,
+ section->name,
+ offset);
}
else {
- fprintf(stderr,"%s", abfd->filename);
+ fprintf(fp,"%s(%s+%0x)", abfd->filename,
+ section->name,
+ offset);
}
}
break;
case 's':
- fprintf(stderr,"%s", va_arg(arg, char *));
+ fprintf(fp,"%s", va_arg(arg, char *));
break;
case 'd':
- fprintf(stderr,"%d", va_arg(arg, int));
+ fprintf(fp,"%d", va_arg(arg, int));
break;
default:
- fprintf(stderr,"%s", va_arg(arg, char *));
+ fprintf(fp,"%s", va_arg(arg, char *));
break;
}
}
unlink(output_filename);
exit(1);
}
+}
+
+/* Format info message and print on stdout. */
+
+void info(va_alist)
+va_dcl
+{
+ char *fmt;
+ va_list arg;
+ va_start(arg);
+ fmt = va_arg(arg, char *);
+ vfinfo(stdout, fmt, arg);
va_end(arg);
}
+/* ('e' for error.) Format info message and print on stderr. */
+
+void einfo(va_alist)
+va_dcl
+{
+ char *fmt;
+ va_list arg;
+ va_start(arg);
+ fmt = va_arg(arg, char *);
+ vfinfo(stderr, fmt, arg);
+ va_end(arg);
+}
void
info_assert(file, line)
char *file;
unsigned int line;
{
- info("%F%P internal error %s %d\n", file,line);
+ einfo("%F%P internal error %s %d\n", file,line);
}
/* Return a newly-allocated string
CONST char *s2 AND
CONST char *s3)
{
- size_t len1 = strlen (s1);
- size_t len2 = strlen (s2);
- size_t len3 = strlen (s3);
+ bfd_size_type len1 = strlen (s1);
+ bfd_size_type len2 = strlen (s2);
+ bfd_size_type len3 = strlen (s3);
char *result = ldmalloc (len1 + len2 + len3 + 1);
if (len1 != 0)
-char *ldmalloc (size)
-size_t size;
+PTR
+DEFUN(ldmalloc, (size),
+bfd_size_type size)
{
- char * result = malloc (size);
+ PTR result = malloc ((int)size);
if (result == (char *)NULL && size != 0)
- info("%F%P virtual memory exhausted\n");
+ einfo("%F%P virtual memory exhausted\n");
return result;
}
char *DEFUN(buystring,(x),
CONST char *CONST x)
{
- size_t l = strlen(x)+1;
+ bfd_size_type l = strlen(x)+1;
char *r = ldmalloc(l);
memcpy(r, x,l);
return r;
}
+
+
+/*----------------------------------------------------------------------
+ Functions to print the link map
+ */
+
+void
+DEFUN_VOID(print_space)
+{
+ printf(" ");
+}
+void
+DEFUN_VOID(print_nl)
+{
+ printf("\n");
+}
+void
+DEFUN(print_address,(value),
+ bfd_vma value)
+{
+ printf_vma(value);
+}
{
fprintf (stdout, " %s\n", f->filename);
if (f->just_syms_flag)
- {
- fprintf (stdout, " symbols only\n");
- }
+ {
+ fprintf (stdout, " symbols only\n");
+ }
else
- {
- asection *s;
- if (true || option_longmap) {
- for (s = f->the_bfd->sections;
- s != (asection *)NULL;
- s = s->next) {
+ {
+ asection *s;
+ if (true || option_longmap) {
+ for (s = f->the_bfd->sections;
+ s != (asection *)NULL;
+ s = s->next) {
print_address(s->output_offset);
- printf (" %08x 2**%2ud %s\n",
- (unsigned)s->size, s->alignment_power, s->name);
+ if (s->flags & SEC_HAS_CONTENTS)
+ {
+ printf (" %08x 2**%2ud %s\n",
+ (unsigned)bfd_get_section_size_after_reloc(s),
+ s->alignment_power, s->name);
+ }
+
+ else
+ {
+ printf (" %08x 2**%2ud %s\n",
+ (unsigned)bfd_get_section_size_before_reloc(s),
+ s->alignment_power, s->name);
+ }
+
+
+
}
- }
- else {
- for (s = f->the_bfd->sections;
- s != (asection *)NULL;
- s = s->next) {
+ }
+ else {
+ for (s = f->the_bfd->sections;
+ s != (asection *)NULL;
+ s = s->next) {
printf("%s ", s->name);
print_address(s->output_offset);
- printf("(%x)", (unsigned)s->size);
+ printf("(%x)", (unsigned)bfd_get_section_size_after_reloc(s));
}
- printf("hex \n");
- }
+ printf("hex \n");
}
+ }
fprintf (stdout, "\n");
}
{
asymbol *p = entry->asymbols[i];
- if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
+ if (flag_is_global(p->flags) )
{
/* We are only interested in outputting
globals at this stage in special circumstances */
*output_buffer++ = p;
}
}
- else if (flag_is_undefined(p->flags))
+ else if (p->section == &bfd_und_section)
{ /* This must be global */
}
- else if (flag_is_common(p->flags)) {
+ else if (p->section == &bfd_com_section) {
/* And so must this */
}
else if (p->flags & BSF_CTOR) {