mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-12 18:51:30 +08:00
Added new keyword 'CONSTRUCTORS'
Added N_WARNING handling Added N_INDR handling
This commit is contained in:
@ -7,21 +7,23 @@ __DYNAMIC = 0;
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
.text 0x2020 BLOCK(0x2000):
|
.text 0x2020 BLOCK(0x2000):
|
||||||
{
|
{
|
||||||
CREATE_OBJECT_SYMBOLS
|
CREATE_OBJECT_SYMBOLS ;
|
||||||
*(.text)
|
*(.text);
|
||||||
_etext = ALIGN( 0x2000);
|
_etext = ALIGN( 0x2000);
|
||||||
}
|
}
|
||||||
.data ALIGN(0x2000) :
|
.data ALIGN(0x2000) :
|
||||||
{
|
{
|
||||||
*(.data)
|
*(.data);
|
||||||
|
CONSTRUCTORS;
|
||||||
_edata = .;
|
_edata = .;
|
||||||
}
|
}
|
||||||
.bss SIZEOF(.data) + ADDR(.data) :
|
.bss SIZEOF(.data) + ADDR(.data) :
|
||||||
{
|
{
|
||||||
*(.bss)
|
*(.bss)
|
||||||
[COMMON]
|
[COMMON]
|
||||||
_end = .;
|
_end = .;
|
||||||
|
__end = .;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,14 +12,7 @@ SECTIONS
|
|||||||
.data SIZEOF(.text) + ADDR(.text) :
|
.data SIZEOF(.text) + ADDR(.text) :
|
||||||
{
|
{
|
||||||
*(.data)
|
*(.data)
|
||||||
___DTOR_LIST__ = . ;
|
CONSTRUCTORS
|
||||||
LONG((___CTOR_LIST__ - .) / 4 -2)
|
|
||||||
*(___DTOR_LIST__)
|
|
||||||
LONG(0)
|
|
||||||
___CTOR_LIST__ = . ;
|
|
||||||
LONG((___end_list__ - .) / 4 -2)
|
|
||||||
*(___CTOR_LIST__)
|
|
||||||
LONG(0)
|
|
||||||
___end_list__ = . ;
|
___end_list__ = . ;
|
||||||
}
|
}
|
||||||
.bss SIZEOF(.data) + ADDR(.data) :
|
.bss SIZEOF(.data) + ADDR(.data) :
|
||||||
|
150
ld/ldlang.c
150
ld/ldlang.c
@ -29,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "ldmain.h"
|
#include "ldmain.h"
|
||||||
#include "ldsym.h"
|
#include "ldsym.h"
|
||||||
#include "ldgram.h"
|
#include "ldgram.h"
|
||||||
|
#include "ldwarn.h"
|
||||||
#include "ldlang.h"
|
#include "ldlang.h"
|
||||||
#include "ldexp.h"
|
#include "ldexp.h"
|
||||||
#include "ldemul.h"
|
#include "ldemul.h"
|
||||||
@ -44,6 +44,14 @@ PROTO(static void, print_statement,(lang_statement_union_type *,
|
|||||||
/* LOCALS */
|
/* LOCALS */
|
||||||
static CONST char *startup_file;
|
static CONST char *startup_file;
|
||||||
static lang_statement_list_type input_file_chain;
|
static lang_statement_list_type input_file_chain;
|
||||||
|
|
||||||
|
/* Points to the last statement in the .data section, so we can add
|
||||||
|
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;
|
||||||
|
|
||||||
static boolean placed_commons = false;
|
static boolean placed_commons = false;
|
||||||
static lang_output_section_statement_type *default_common_section;
|
static lang_output_section_statement_type *default_common_section;
|
||||||
static boolean map_option_f;
|
static boolean map_option_f;
|
||||||
@ -97,6 +105,8 @@ extern boolean write_map;
|
|||||||
|
|
||||||
#define outside_symbol_address(q) ((q)->value + outside_section_address(q->section))
|
#define outside_symbol_address(q) ((q)->value + outside_section_address(q->section))
|
||||||
|
|
||||||
|
static void EXFUN(lang_add_data,( int type , union etree_union *exp));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DEFUN(print_size,(value),
|
DEFUN(print_size,(value),
|
||||||
size_t value)
|
size_t value)
|
||||||
@ -139,6 +149,9 @@ DEFUN(lang_for_each_statement_worker,(func, s),
|
|||||||
func(s);
|
func(s);
|
||||||
|
|
||||||
switch (s->header.type) {
|
switch (s->header.type) {
|
||||||
|
case lang_constructors_statement_enum:
|
||||||
|
lang_for_each_statement_worker(func, constructor_list.head);
|
||||||
|
break;
|
||||||
case lang_output_section_statement_enum:
|
case lang_output_section_statement_enum:
|
||||||
lang_for_each_statement_worker
|
lang_for_each_statement_worker
|
||||||
(func,
|
(func,
|
||||||
@ -839,13 +852,19 @@ DEFUN(map_input_to_output_sections,(s, target, output_section_statement),
|
|||||||
for (; s != (lang_statement_union_type *)NULL ; s = s->next)
|
for (; s != (lang_statement_union_type *)NULL ; s = s->next)
|
||||||
{
|
{
|
||||||
switch (s->header.type) {
|
switch (s->header.type) {
|
||||||
|
|
||||||
|
|
||||||
case lang_wild_statement_enum:
|
case lang_wild_statement_enum:
|
||||||
wild(&s->wild_statement, s->wild_statement.section_name,
|
wild(&s->wild_statement, s->wild_statement.section_name,
|
||||||
s->wild_statement.filename, target,
|
s->wild_statement.filename, target,
|
||||||
output_section_statement);
|
output_section_statement);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case lang_constructors_statement_enum:
|
||||||
|
map_input_to_output_sections(constructor_list.head,
|
||||||
|
target,
|
||||||
|
output_section_statement);
|
||||||
|
break;
|
||||||
case lang_output_section_statement_enum:
|
case lang_output_section_statement_enum:
|
||||||
map_input_to_output_sections(s->output_section_statement.children.head,
|
map_input_to_output_sections(s->output_section_statement.children.head,
|
||||||
target,
|
target,
|
||||||
@ -1135,6 +1154,11 @@ DEFUN(print_statement,(s, os),
|
|||||||
{
|
{
|
||||||
while (s) {
|
while (s) {
|
||||||
switch (s->header.type) {
|
switch (s->header.type) {
|
||||||
|
case lang_constructors_statement_enum:
|
||||||
|
printf("constructors:\n");
|
||||||
|
print_statement(constructor_list.head, os);
|
||||||
|
break;
|
||||||
|
|
||||||
case lang_wild_statement_enum:
|
case lang_wild_statement_enum:
|
||||||
print_wild_statement(&s->wild_statement, os);
|
print_wild_statement(&s->wild_statement, os);
|
||||||
break;
|
break;
|
||||||
@ -1297,6 +1321,8 @@ DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot),
|
|||||||
for (; s != (lang_statement_union_type *)NULL ; s = s->next)
|
for (; s != (lang_statement_union_type *)NULL ; s = s->next)
|
||||||
{
|
{
|
||||||
switch (s->header.type) {
|
switch (s->header.type) {
|
||||||
|
|
||||||
|
|
||||||
case lang_output_section_statement_enum:
|
case lang_output_section_statement_enum:
|
||||||
{
|
{
|
||||||
bfd_vma after;
|
bfd_vma after;
|
||||||
@ -1355,7 +1381,14 @@ DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot),
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case lang_constructors_statement_enum:
|
||||||
|
dot = lang_size_sections(constructor_list.head,
|
||||||
|
output_section_statement,
|
||||||
|
&s->wild_statement.children.head,
|
||||||
|
fill,
|
||||||
|
dot);
|
||||||
|
break;
|
||||||
|
|
||||||
case lang_data_statement_enum:
|
case lang_data_statement_enum:
|
||||||
{
|
{
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
@ -1464,6 +1497,13 @@ DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot),
|
|||||||
for (; s != (lang_statement_union_type *)NULL ; s = s->next)
|
for (; s != (lang_statement_union_type *)NULL ; s = s->next)
|
||||||
{
|
{
|
||||||
switch (s->header.type) {
|
switch (s->header.type) {
|
||||||
|
case lang_constructors_statement_enum:
|
||||||
|
dot = lang_do_assignments(constructor_list.head,
|
||||||
|
output_section_statement,
|
||||||
|
fill,
|
||||||
|
dot);
|
||||||
|
break;
|
||||||
|
|
||||||
case lang_output_section_statement_enum:
|
case lang_output_section_statement_enum:
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os =
|
lang_output_section_statement_type *os =
|
||||||
@ -1576,7 +1616,15 @@ DEFUN_VOID(lang_relocate_globals)
|
|||||||
}
|
}
|
||||||
if (it != (asymbol *)NULL)
|
if (it != (asymbol *)NULL)
|
||||||
{
|
{
|
||||||
asymbol **ptr= lgs->srefs_chain;
|
asymbol **ptr = lgs->srefs_chain;;
|
||||||
|
if (lgs->flags & SYM_WARNING)
|
||||||
|
{
|
||||||
|
produce_warnings(lgs, it);
|
||||||
|
}
|
||||||
|
if (lgs->flags & SYM_INDIRECT)
|
||||||
|
{
|
||||||
|
do_indirect(lgs);
|
||||||
|
}
|
||||||
|
|
||||||
while (ptr != (asymbol **)NULL) {
|
while (ptr != (asymbol **)NULL) {
|
||||||
asymbol *ref = *ptr;
|
asymbol *ref = *ptr;
|
||||||
@ -1938,7 +1986,8 @@ DEFUN(lang_enter_output_section_statement,
|
|||||||
os =
|
os =
|
||||||
lang_output_section_statement_lookup(output_section_statement_name);
|
lang_output_section_statement_lookup(output_section_statement_name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Add this statement to tree */
|
/* Add this statement to tree */
|
||||||
/* add_statement(lang_output_section_statement_enum,
|
/* add_statement(lang_output_section_statement_enum,
|
||||||
output_section_statement);*/
|
output_section_statement);*/
|
||||||
@ -1989,7 +2038,88 @@ DEFUN(create_symbol,(name, flags, section),
|
|||||||
return def;
|
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
|
void
|
||||||
DEFUN_VOID(lang_process)
|
DEFUN_VOID(lang_process)
|
||||||
{
|
{
|
||||||
@ -2016,12 +2146,15 @@ DEFUN_VOID(lang_process)
|
|||||||
|
|
||||||
common_section.userdata = (PTR)&common_section_userdata;
|
common_section.userdata = (PTR)&common_section_userdata;
|
||||||
|
|
||||||
|
|
||||||
/* Run through the contours of the script and attatch input sections
|
/* Run through the contours of the script and attatch input sections
|
||||||
to the correct output sections
|
to the correct output sections
|
||||||
*/
|
*/
|
||||||
|
find_constructors();
|
||||||
map_input_to_output_sections(statement_list.head, (char *)NULL,
|
map_input_to_output_sections(statement_list.head, (char *)NULL,
|
||||||
( lang_output_section_statement_type *)NULL);
|
( lang_output_section_statement_type *)NULL);
|
||||||
|
|
||||||
|
|
||||||
/* Find any sections not attatched explicitly and handle them */
|
/* Find any sections not attatched explicitly and handle them */
|
||||||
lang_place_orphans();
|
lang_place_orphans();
|
||||||
|
|
||||||
@ -2189,6 +2322,13 @@ DEFUN(lang_leave_output_section_statement,(fill, memspec),
|
|||||||
current_section->fill = fill;
|
current_section->fill = fill;
|
||||||
current_section->region = lang_memory_region_lookup(memspec);
|
current_section->region = lang_memory_region_lookup(memspec);
|
||||||
stat_ptr = &statement_list;
|
stat_ptr = &statement_list;
|
||||||
|
|
||||||
|
/* We remember if we are closing a .data section, since we use it to
|
||||||
|
store constructors in */
|
||||||
|
if (strcmp(current_section->name, ".data") ==0) {
|
||||||
|
end_of_data_section_statement_list = statement_list;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Create an absolute symbol with the given name with the value of the
|
Create an absolute symbol with the given name with the value of the
|
||||||
|
211
ld/ldmain.c
211
ld/ldmain.c
@ -101,6 +101,10 @@ boolean write_map;
|
|||||||
|
|
||||||
|
|
||||||
int unix_relocate;
|
int unix_relocate;
|
||||||
|
#ifdef GNU960
|
||||||
|
/* Indicates whether output file will be b.out (default) or coff */
|
||||||
|
enum target_flavour_enum output_flavor = BFD_BOUT_FORMAT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -139,11 +143,23 @@ main (argc, argv)
|
|||||||
output_filename = "a.out";
|
output_filename = "a.out";
|
||||||
|
|
||||||
#ifdef GNU960
|
#ifdef GNU960
|
||||||
check_v960( argc, argv );
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
check_v960( argc, argv );
|
||||||
|
emulation = GLD960_EMULATION_NAME;
|
||||||
|
for ( i = 1; i < argc; i++ ){
|
||||||
|
if ( !strcmp(argv[i],"-Fcoff") ){
|
||||||
|
emulation = LNK960_EMULATION_NAME;
|
||||||
|
output_flavor = BFD_COFF_FORMAT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
emulation = (char *) getenv(EMULATION_ENVIRON);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
emulation = (char *) getenv(EMULATION_ENVIRON);
|
|
||||||
|
|
||||||
/* Initialize the data about options. */
|
/* Initialize the data about options. */
|
||||||
|
|
||||||
trace_files = false;
|
trace_files = false;
|
||||||
@ -168,17 +184,13 @@ main (argc, argv)
|
|||||||
|
|
||||||
config.magic_demand_paged = true ;
|
config.magic_demand_paged = true ;
|
||||||
config.make_executable = true;
|
config.make_executable = true;
|
||||||
|
|
||||||
#ifdef GNU960
|
|
||||||
ldemul_choose_mode(LNK960_EMULATION_NAME);
|
|
||||||
#else
|
|
||||||
if (emulation == (char *)NULL) {
|
if (emulation == (char *)NULL) {
|
||||||
emulation= DEFAULT_EMULATION;
|
emulation= DEFAULT_EMULATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ldemul_choose_mode(emulation);
|
ldemul_choose_mode(emulation);
|
||||||
#endif
|
|
||||||
|
|
||||||
default_target = ldemul_choose_target();
|
default_target = ldemul_choose_target();
|
||||||
|
|
||||||
@ -239,7 +251,7 @@ Q_read_entry_symbols (desc, entry)
|
|||||||
struct lang_input_statement_struct *entry;
|
struct lang_input_statement_struct *entry;
|
||||||
{
|
{
|
||||||
if (entry->asymbols == (asymbol **)NULL) {
|
if (entry->asymbols == (asymbol **)NULL) {
|
||||||
size_t table_size = get_symtab_upper_bound(desc);
|
bfd_size_type table_size = get_symtab_upper_bound(desc);
|
||||||
entry->asymbols = (asymbol **)ldmalloc(table_size);
|
entry->asymbols = (asymbol **)ldmalloc(table_size);
|
||||||
|
|
||||||
entry->symbol_count = bfd_canonicalize_symtab(desc, entry->asymbols) ;
|
entry->symbol_count = bfd_canonicalize_symtab(desc, entry->asymbols) ;
|
||||||
@ -300,95 +312,102 @@ Q_enter_global_ref (nlist_p)
|
|||||||
|
|
||||||
ASSERT(sym->udata == 0);
|
ASSERT(sym->udata == 0);
|
||||||
|
|
||||||
/* Just place onto correct chain */
|
if (flag_is_constructor(this_symbol_flags)) {
|
||||||
if (flag_is_common(this_symbol_flags)) {
|
/* Just remeber the name, do it once per name by placing it as if
|
||||||
/* If we have a definition of this symbol already then
|
it were a zero sized common. The next ref */
|
||||||
* this common turns into a reference. Also we only
|
ldlang_add_constructor(sp);
|
||||||
* ever point to the largest common, so if we
|
|
||||||
* have a common, but it's bigger that the new symbol
|
}
|
||||||
* the turn this into a reference too.
|
else {
|
||||||
*/
|
if (flag_is_common(this_symbol_flags)) {
|
||||||
if (sp->sdefs_chain)
|
/* If we have a definition of this symbol already then
|
||||||
{
|
* this common turns into a reference. Also we only
|
||||||
/* This is a common symbol, but we already have a definition
|
* ever point to the largest common, so if we
|
||||||
for it, so just link it into the ref chain as if
|
* have a common, but it's bigger that the new symbol
|
||||||
it were a reference
|
* the turn this into a reference too.
|
||||||
*/
|
*/
|
||||||
refize(sp, nlist_p);
|
if (sp->sdefs_chain)
|
||||||
|
{
|
||||||
|
/* This is a common symbol, but we already have a definition
|
||||||
|
for it, so just link it into the ref chain as if
|
||||||
|
it were a reference
|
||||||
|
*/
|
||||||
|
refize(sp, nlist_p);
|
||||||
|
}
|
||||||
|
else if (sp->scoms_chain) {
|
||||||
|
/* If we have a previous common, keep only the biggest */
|
||||||
|
if ( (*(sp->scoms_chain))->value > sym->value) {
|
||||||
|
/* other common is bigger, throw this one away */
|
||||||
|
refize(sp, nlist_p);
|
||||||
|
}
|
||||||
|
else if (sp->scoms_chain != nlist_p) {
|
||||||
|
/* other common is smaller, throw that away */
|
||||||
|
refize(sp, sp->scoms_chain);
|
||||||
|
sp->scoms_chain = nlist_p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (sp->scoms_chain) {
|
else {
|
||||||
/* If we have a previous common, keep only the biggest */
|
/* This is the first time we've seen a common, so
|
||||||
if ( (*(sp->scoms_chain))->value > sym->value) {
|
* remember it - if it was undefined before, we know it's defined now
|
||||||
/* other common is bigger, throw this one away */
|
*/
|
||||||
refize(sp, nlist_p);
|
if (sp->srefs_chain)
|
||||||
}
|
undefined_global_sym_count--;
|
||||||
else if (sp->scoms_chain != nlist_p) {
|
|
||||||
/* other common is smaller, throw that away */
|
commons_pending++;
|
||||||
refize(sp, sp->scoms_chain);
|
|
||||||
sp->scoms_chain = nlist_p;
|
sp->scoms_chain = nlist_p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
/* This is the first time we've seen a common, so
|
|
||||||
* remember it - if it was undefined before, we know it's defined now
|
|
||||||
*/
|
|
||||||
if (sp->srefs_chain)
|
|
||||||
undefined_global_sym_count--;
|
|
||||||
|
|
||||||
commons_pending++;
|
else if (flag_is_defined(this_symbol_flags)) {
|
||||||
sp->scoms_chain = nlist_p;
|
/* This is the definition of a symbol, add to def chain */
|
||||||
}
|
if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section) {
|
||||||
}
|
/* Multiple definition */
|
||||||
|
asymbol *sy = *(sp->sdefs_chain);
|
||||||
else if (flag_is_defined(this_symbol_flags)) {
|
lang_input_statement_type *stat = (lang_input_statement_type *) sy->the_bfd->usrdata;
|
||||||
/* This is the definition of a symbol, add to def chain */
|
lang_input_statement_type *stat1 = (lang_input_statement_type *) sym->the_bfd->usrdata;
|
||||||
if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section) {
|
asymbol ** stat1_symbols = stat1 ? stat1->asymbols: 0;
|
||||||
/* Multiple definition */
|
asymbol ** stat_symbols = stat ? stat->asymbols:0;
|
||||||
asymbol *sy = *(sp->sdefs_chain);
|
|
||||||
lang_input_statement_type *stat = (lang_input_statement_type *) sy->the_bfd->usrdata;
|
|
||||||
lang_input_statement_type *stat1 = (lang_input_statement_type *) sym->the_bfd->usrdata;
|
|
||||||
asymbol ** stat1_symbols = stat1 ? stat1->asymbols: 0;
|
|
||||||
asymbol ** stat_symbols = stat ? stat->asymbols:0;
|
|
||||||
|
|
||||||
multiple_def_count++;
|
multiple_def_count++;
|
||||||
info("%C: multiple definition of `%T'\n",
|
info("%C: multiple definition of `%T'\n",
|
||||||
sym->the_bfd,
|
sym->the_bfd,
|
||||||
sym->section,
|
sym->section,
|
||||||
stat1_symbols,
|
stat1_symbols,
|
||||||
sym->value,
|
sym->value,
|
||||||
sym);
|
sym);
|
||||||
|
|
||||||
info("%C: first seen here\n",
|
info("%C: first seen here\n",
|
||||||
sy->the_bfd,
|
sy->the_bfd,
|
||||||
sy->section,
|
sy->section,
|
||||||
stat_symbols,
|
stat_symbols,
|
||||||
sy->value);
|
sy->value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sym->udata =(PTR)( sp->sdefs_chain);
|
||||||
|
sp->sdefs_chain = nlist_p;
|
||||||
|
}
|
||||||
|
/* A definition overrides a common symbol */
|
||||||
|
if (sp->scoms_chain) {
|
||||||
|
refize(sp, sp->scoms_chain);
|
||||||
|
sp->scoms_chain = 0;
|
||||||
|
commons_pending--;
|
||||||
|
}
|
||||||
|
else if (sp->srefs_chain) {
|
||||||
|
/* If previously was undefined, then remember as defined */
|
||||||
|
undefined_global_sym_count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sym->udata =(PTR)( sp->sdefs_chain);
|
if (sp->scoms_chain == (asymbol **)NULL
|
||||||
sp->sdefs_chain = nlist_p;
|
&& sp->srefs_chain == (asymbol **)NULL
|
||||||
}
|
&& sp->sdefs_chain == (asymbol **)NULL) {
|
||||||
/* A definition overrides a common symbol */
|
/* And it's the first time we've seen it */
|
||||||
if (sp->scoms_chain) {
|
undefined_global_sym_count++;
|
||||||
refize(sp, sp->scoms_chain);
|
|
||||||
sp->scoms_chain = 0;
|
|
||||||
commons_pending--;
|
|
||||||
}
|
|
||||||
else if (sp->srefs_chain) {
|
|
||||||
/* If previously was undefined, then remember as defined */
|
|
||||||
undefined_global_sym_count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (sp->scoms_chain == (asymbol **)NULL
|
|
||||||
&& sp->srefs_chain == (asymbol **)NULL
|
|
||||||
&& sp->sdefs_chain == (asymbol **)NULL) {
|
|
||||||
/* And it's the first time we've seen it */
|
|
||||||
undefined_global_sym_count++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refize(sp, nlist_p);
|
refize(sp, nlist_p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(sp->sdefs_chain == 0 || sp->scoms_chain == 0);
|
ASSERT(sp->sdefs_chain == 0 || sp->scoms_chain == 0);
|
||||||
@ -418,10 +437,17 @@ lang_input_statement_type *entry;
|
|||||||
{
|
{
|
||||||
asymbol *p = *q;
|
asymbol *p = *q;
|
||||||
|
|
||||||
if (flag_is_undefined_or_global_or_common(p->flags))
|
if (flag_is_undefined_or_global_or_common_or_constructor(p->flags))
|
||||||
{
|
{
|
||||||
Q_enter_global_ref(q);
|
Q_enter_global_ref(q);
|
||||||
}
|
}
|
||||||
|
if (p->flags & BSF_INDIRECT) {
|
||||||
|
add_indirect(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->flags & BSF_WARNING) {
|
||||||
|
add_warning(p);
|
||||||
|
}
|
||||||
ASSERT(p->flags != 0);
|
ASSERT(p->flags != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,9 +489,12 @@ bfd_format format;
|
|||||||
{
|
{
|
||||||
boolean retval;
|
boolean retval;
|
||||||
|
|
||||||
if ((bfd_check_format(abfd,format) == true) && BFD_COFF_FILE_P(abfd)) {
|
if ((bfd_check_format(abfd,format) == true)
|
||||||
return true;
|
&& (abfd->xvec->flavour == output_flavor) ){
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -525,7 +554,7 @@ decode_library_subfile (library_entry, subfile_offset)
|
|||||||
bfd *subfile_offset;
|
bfd *subfile_offset;
|
||||||
{
|
{
|
||||||
register struct lang_input_statement_struct *subentry;
|
register struct lang_input_statement_struct *subentry;
|
||||||
subentry = (struct lang_input_statement_struct *) ldmalloc (sizeof (struct lang_input_statement_struct));
|
subentry = (struct lang_input_statement_struct *) ldmalloc ((bfd_size_type)(sizeof (struct lang_input_statement_struct)));
|
||||||
subentry->filename = subfile_offset -> filename;
|
subentry->filename = subfile_offset -> filename;
|
||||||
subentry->local_sym_name = subfile_offset->filename;
|
subentry->local_sym_name = subfile_offset->filename;
|
||||||
subentry->asymbols = 0;
|
subentry->asymbols = 0;
|
||||||
|
@ -103,7 +103,7 @@ DEFUN(ldsym_get,(key),
|
|||||||
bp->sdefs_chain = (asymbol **)NULL;
|
bp->sdefs_chain = (asymbol **)NULL;
|
||||||
bp->scoms_chain = (asymbol **)NULL;
|
bp->scoms_chain = (asymbol **)NULL;
|
||||||
bp->name = buystring(key);
|
bp->name = buystring(key);
|
||||||
|
bp->flags = 0;
|
||||||
/* Add the entry to the bucket. */
|
/* Add the entry to the bucket. */
|
||||||
|
|
||||||
bp->link = global_symbol_hash_table[hashval];
|
bp->link = global_symbol_hash_table[hashval];
|
||||||
|
11
ld/ldsym.h
11
ld/ldsym.h
@ -44,6 +44,17 @@ typedef struct user_symbol_struct
|
|||||||
*/
|
*/
|
||||||
asymbol **scoms_chain;
|
asymbol **scoms_chain;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* If this symbol is a constructor */
|
||||||
|
#define SYM_CONSTRUCTOR 1
|
||||||
|
/* If this symbol is a warning symbol */
|
||||||
|
#define SYM_WARNING 2
|
||||||
|
/* IF this is an alias for another symbol */
|
||||||
|
#define SYM_INDIRECT 4
|
||||||
|
int flags;
|
||||||
} ldsym_type;
|
} ldsym_type;
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,4 +19,6 @@
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
|
||||||
PROTOX(void, ldwarn,(void));
|
|
||||||
|
void EXFUN(add_warning,(asymbol *));
|
||||||
|
CONST char * EXFUN(fetch_warning,(asymbol *));
|
||||||
|
Reference in New Issue
Block a user