Added new keyword 'CONSTRUCTORS'

Added N_WARNING handling
Added N_INDR handling
This commit is contained in:
Steve Chamberlain
1991-08-01 23:29:23 +00:00
parent 812df84bc9
commit 8101605119
7 changed files with 294 additions and 117 deletions

View File

@ -8,13 +8,14 @@ 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) :
@ -22,6 +23,7 @@ SECTIONS
*(.bss) *(.bss)
[COMMON] [COMMON]
_end = .; _end = .;
__end = .;
} }
} }

View File

@ -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) :

View File

@ -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,6 +1381,13 @@ 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:
{ {
@ -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;
@ -1939,6 +1987,7 @@ DEFUN(lang_enter_output_section_statement,
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

View File

@ -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,10 +143,22 @@ main (argc, argv)
output_filename = "a.out"; output_filename = "a.out";
#ifdef GNU960 #ifdef GNU960
check_v960( argc, argv ); {
#endif 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); emulation = (char *) getenv(EMULATION_ENVIRON);
#endif
/* Initialize the data about options. */ /* Initialize the data about options. */
@ -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,7 +312,13 @@ 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)) {
/* Just remeber the name, do it once per name by placing it as if
it were a zero sized common. The next ref */
ldlang_add_constructor(sp);
}
else {
if (flag_is_common(this_symbol_flags)) { if (flag_is_common(this_symbol_flags)) {
/* If we have a definition of this symbol already then /* If we have a definition of this symbol already then
* this common turns into a reference. Also we only * this common turns into a reference. Also we only
@ -390,6 +408,7 @@ Q_enter_global_ref (nlist_p)
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);
ASSERT(sp->scoms_chain ==0 || (*(sp->scoms_chain))->udata == 0); ASSERT(sp->scoms_chain ==0 || (*(sp->scoms_chain))->udata == 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)
&& (abfd->xvec->flavour == output_flavor) ){
return true; 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;

View File

@ -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];

View File

@ -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;

View File

@ -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 *));