mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 23:39:35 +08:00
* xcofflink.c (XCOFF_DESCRIPTOR): Define.
(struct xcoff_link_hash_table): Add descriptor_section and special_sections fields. (_bfd_xcoff_bfd_link_hash_table_create): Initialize new fields. (xcoff_link_add_symbols): Set linkage section alignment. Create descriptor section. Check for magic symbol names (_text, etc.), and record them in special_sections if found. Set XCOFF_DESCRIPTOR flag for a function descriptor, and set its descriptor field to point back to the function code symbol. (xcoff_sweep): Always mark the special descriptor_section. (bfd_xcoff_export_symbol): Check whether the symbol might be a function descriptor, and mark it if it is. (bfd_xcoff_size_dynamic_sections): Add new special_sections parameter, and fill it in. Allocate space for the descriptor section. (xcoff_build_ldsyms): Set XCOFF_DEF_REGULAR flag when defining global linkage code. If an undefined function descriptor is exported, arrange to define it. Warn about any other undefined exported symbol. (_bfd_xcoff_bfd_final_link): Write out the descriptor section. (xcoff_write_global_symbol): Create a function descriptor when necessary. * bfd-in.h (bfd_xcoff_size_dynamic_sections): Update declaration. * bfd-in2.h: Rebuild.
This commit is contained in:
@ -1,3 +1,30 @@
|
|||||||
|
Thu Nov 9 13:01:31 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
|
* xcofflink.c (XCOFF_DESCRIPTOR): Define.
|
||||||
|
(struct xcoff_link_hash_table): Add descriptor_section and
|
||||||
|
special_sections fields.
|
||||||
|
(_bfd_xcoff_bfd_link_hash_table_create): Initialize new fields.
|
||||||
|
(xcoff_link_add_symbols): Set linkage section alignment. Create
|
||||||
|
descriptor section. Check for magic symbol names (_text, etc.),
|
||||||
|
and record them in special_sections if found. Set
|
||||||
|
XCOFF_DESCRIPTOR flag for a function descriptor, and set its
|
||||||
|
descriptor field to point back to the function code symbol.
|
||||||
|
(xcoff_sweep): Always mark the special descriptor_section.
|
||||||
|
(bfd_xcoff_export_symbol): Check whether the symbol might be a
|
||||||
|
function descriptor, and mark it if it is.
|
||||||
|
(bfd_xcoff_size_dynamic_sections): Add new special_sections
|
||||||
|
parameter, and fill it in. Allocate space for the descriptor
|
||||||
|
section.
|
||||||
|
(xcoff_build_ldsyms): Set XCOFF_DEF_REGULAR flag when defining
|
||||||
|
global linkage code. If an undefined function descriptor is
|
||||||
|
exported, arrange to define it. Warn about any other undefined
|
||||||
|
exported symbol.
|
||||||
|
(_bfd_xcoff_bfd_final_link): Write out the descriptor section.
|
||||||
|
(xcoff_write_global_symbol): Create a function descriptor when
|
||||||
|
necessary.
|
||||||
|
* bfd-in.h (bfd_xcoff_size_dynamic_sections): Update declaration.
|
||||||
|
* bfd-in2.h: Rebuild.
|
||||||
|
|
||||||
Thu Nov 9 08:40:23 1995 Kim Knuttila <krk@cygnus.com>
|
Thu Nov 9 08:40:23 1995 Kim Knuttila <krk@cygnus.com>
|
||||||
|
|
||||||
* coff-ppc.c (ppc_coff_link_hash_entry): new types for hashing
|
* coff-ppc.c (ppc_coff_link_hash_entry): new types for hashing
|
||||||
|
289
bfd/xcofflink.c
289
bfd/xcofflink.c
@ -261,7 +261,9 @@ struct xcoff_link_hash_entry
|
|||||||
} u;
|
} u;
|
||||||
|
|
||||||
/* If this symbol is a function entry point which is called, this
|
/* If this symbol is a function entry point which is called, this
|
||||||
field holds a pointer to the function descriptor. */
|
field holds a pointer to the function descriptor. If this symbol
|
||||||
|
is a function descriptor, this field holds a pointer to the
|
||||||
|
function entry point. */
|
||||||
struct xcoff_link_hash_entry *descriptor;
|
struct xcoff_link_hash_entry *descriptor;
|
||||||
|
|
||||||
/* The .loader symbol table entry, if there is one. */
|
/* The .loader symbol table entry, if there is one. */
|
||||||
@ -296,6 +298,8 @@ struct xcoff_link_hash_entry
|
|||||||
#define XCOFF_MARK (02000)
|
#define XCOFF_MARK (02000)
|
||||||
/* Symbol size is recorded in size_list list from hash table. */
|
/* Symbol size is recorded in size_list list from hash table. */
|
||||||
#define XCOFF_HAS_SIZE (04000)
|
#define XCOFF_HAS_SIZE (04000)
|
||||||
|
/* Symbol is a function descriptor. */
|
||||||
|
#define XCOFF_DESCRIPTOR (010000)
|
||||||
|
|
||||||
/* The storage mapping class. */
|
/* The storage mapping class. */
|
||||||
unsigned char smclas;
|
unsigned char smclas;
|
||||||
@ -332,6 +336,10 @@ struct xcoff_link_hash_table
|
|||||||
linkage code. */
|
linkage code. */
|
||||||
asection *toc_section;
|
asection *toc_section;
|
||||||
|
|
||||||
|
/* The .ds section we use to hold function descriptors which we
|
||||||
|
create for exported symbols. */
|
||||||
|
asection *descriptor_section;
|
||||||
|
|
||||||
/* The list of import files. */
|
/* The list of import files. */
|
||||||
struct xcoff_import_file *imports;
|
struct xcoff_import_file *imports;
|
||||||
|
|
||||||
@ -351,6 +359,9 @@ struct xcoff_link_hash_table
|
|||||||
struct xcoff_link_hash_entry *h;
|
struct xcoff_link_hash_entry *h;
|
||||||
bfd_size_type size;
|
bfd_size_type size;
|
||||||
} *size_list;
|
} *size_list;
|
||||||
|
|
||||||
|
/* Magic sections: _text, _etext, _data, _edata, _end, end. */
|
||||||
|
asection *special_sections[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information we keep for each section in the output file during the
|
/* Information we keep for each section in the output file during the
|
||||||
@ -627,10 +638,12 @@ _bfd_xcoff_bfd_link_hash_table_create (abfd)
|
|||||||
memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr));
|
memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr));
|
||||||
ret->linkage_section = NULL;
|
ret->linkage_section = NULL;
|
||||||
ret->toc_section = NULL;
|
ret->toc_section = NULL;
|
||||||
|
ret->descriptor_section = NULL;
|
||||||
ret->imports = NULL;
|
ret->imports = NULL;
|
||||||
ret->file_align = 0;
|
ret->file_align = 0;
|
||||||
ret->textro = false;
|
ret->textro = false;
|
||||||
ret->gc = false;
|
ret->gc = false;
|
||||||
|
memset (ret->special_sections, 0, sizeof ret->special_sections);
|
||||||
|
|
||||||
/* The linker will always generate a full a.out header. We need to
|
/* The linker will always generate a full a.out header. We need to
|
||||||
record that fact now, before the sizeof_headers routine could be
|
record that fact now, before the sizeof_headers routine could be
|
||||||
@ -978,6 +991,7 @@ xcoff_link_add_symbols (abfd, info)
|
|||||||
goto error_return;
|
goto error_return;
|
||||||
xcoff_hash_table (info)->linkage_section = lsec;
|
xcoff_hash_table (info)->linkage_section = lsec;
|
||||||
lsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
|
lsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
|
||||||
|
lsec->alignment_power = 2;
|
||||||
}
|
}
|
||||||
/* Likewise for the TOC section. */
|
/* Likewise for the TOC section. */
|
||||||
if (xcoff_hash_table (info)->toc_section == NULL)
|
if (xcoff_hash_table (info)->toc_section == NULL)
|
||||||
@ -991,6 +1005,18 @@ xcoff_link_add_symbols (abfd, info)
|
|||||||
tsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
|
tsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
|
||||||
tsec->alignment_power = 2;
|
tsec->alignment_power = 2;
|
||||||
}
|
}
|
||||||
|
/* Likewise for the descriptor section. */
|
||||||
|
if (xcoff_hash_table (info)->descriptor_section == NULL)
|
||||||
|
{
|
||||||
|
asection *dsec;
|
||||||
|
|
||||||
|
dsec = bfd_make_section_anyway (abfd, ".ds");
|
||||||
|
if (dsec == NULL)
|
||||||
|
goto error_return;
|
||||||
|
xcoff_hash_table (info)->descriptor_section = dsec;
|
||||||
|
dsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
|
||||||
|
dsec->alignment_power = 2;
|
||||||
|
}
|
||||||
/* Likewise for the .debug section. */
|
/* Likewise for the .debug section. */
|
||||||
if (xcoff_hash_table (info)->debug_section == NULL)
|
if (xcoff_hash_table (info)->debug_section == NULL)
|
||||||
{
|
{
|
||||||
@ -1623,6 +1649,33 @@ xcoff_link_add_symbols (abfd, info)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for magic symbol names. */
|
||||||
|
if ((smtyp == XTY_SD || smtyp == XTY_CM)
|
||||||
|
&& aux.x_csect.x_smclas != XMC_TC)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = -1;
|
||||||
|
if (name[0] == '_')
|
||||||
|
{
|
||||||
|
if (strcmp (name, "_text") == 0)
|
||||||
|
i = 0;
|
||||||
|
else if (strcmp (name, "_etext") == 0)
|
||||||
|
i = 1;
|
||||||
|
else if (strcmp (name, "_data") == 0)
|
||||||
|
i = 2;
|
||||||
|
else if (strcmp (name, "_edata") == 0)
|
||||||
|
i = 3;
|
||||||
|
else if (strcmp (name, "_end") == 0)
|
||||||
|
i = 4;
|
||||||
|
}
|
||||||
|
else if (name[0] == 'e' && strcmp (name, "end") == 0)
|
||||||
|
i = 5;
|
||||||
|
|
||||||
|
if (i != -1)
|
||||||
|
xcoff_hash_table (info)->special_sections[i] = csect;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now we have enough information to add the symbol to the
|
/* Now we have enough information to add the symbol to the
|
||||||
linker hash table. */
|
linker hash table. */
|
||||||
|
|
||||||
@ -1800,6 +1853,10 @@ xcoff_link_add_symbols (abfd, info)
|
|||||||
(struct bfd_link_hash_entry **) &hds)))
|
(struct bfd_link_hash_entry **) &hds)))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
hds->flags |= XCOFF_DESCRIPTOR;
|
||||||
|
BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0
|
||||||
|
&& (h->flags & XCOFF_DESCRIPTOR) == 0);
|
||||||
|
hds->descriptor = h;
|
||||||
h->descriptor = hds;
|
h->descriptor = hds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2250,6 +2307,7 @@ xcoff_sweep (info)
|
|||||||
|| o == xcoff_hash_table (info)->loader_section
|
|| o == xcoff_hash_table (info)->loader_section
|
||||||
|| o == xcoff_hash_table (info)->linkage_section
|
|| o == xcoff_hash_table (info)->linkage_section
|
||||||
|| o == xcoff_hash_table (info)->toc_section
|
|| o == xcoff_hash_table (info)->toc_section
|
||||||
|
|| o == xcoff_hash_table (info)->descriptor_section
|
||||||
|| strcmp (o->name, ".debug") == 0)
|
|| strcmp (o->name, ".debug") == 0)
|
||||||
o->flags |= SEC_MARK;
|
o->flags |= SEC_MARK;
|
||||||
else
|
else
|
||||||
@ -2411,10 +2469,51 @@ bfd_xcoff_export_symbol (output_bfd, info, harg, syscall)
|
|||||||
/* FIXME: I'm not at all sure what syscall is supposed to mean, so
|
/* FIXME: I'm not at all sure what syscall is supposed to mean, so
|
||||||
I'm just going to ignore it until somebody explains it. */
|
I'm just going to ignore it until somebody explains it. */
|
||||||
|
|
||||||
|
/* See if this is a function descriptor. It may be one even though
|
||||||
|
it is not so marked. */
|
||||||
|
if ((h->flags & XCOFF_DESCRIPTOR) == 0
|
||||||
|
&& h->root.root.string[0] != '.')
|
||||||
|
{
|
||||||
|
char *fnname;
|
||||||
|
struct xcoff_link_hash_entry *hfn;
|
||||||
|
|
||||||
|
fnname = (char *) malloc (strlen (h->root.root.string + 2));
|
||||||
|
if (fnname == NULL)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_no_memory);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fnname[0] = '.';
|
||||||
|
strcpy (fnname + 1, h->root.root.string);
|
||||||
|
hfn = xcoff_link_hash_lookup (xcoff_hash_table (info),
|
||||||
|
fnname, false, false, true);
|
||||||
|
free (fnname);
|
||||||
|
if (hfn != NULL
|
||||||
|
&& hfn->smclas == XMC_PR
|
||||||
|
&& (hfn->root.type == bfd_link_hash_defined
|
||||||
|
|| hfn->root.type == bfd_link_hash_defweak))
|
||||||
|
{
|
||||||
|
h->flags |= XCOFF_DESCRIPTOR;
|
||||||
|
h->descriptor = hfn;
|
||||||
|
hfn->descriptor = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure we don't garbage collect this symbol. */
|
/* Make sure we don't garbage collect this symbol. */
|
||||||
if (! xcoff_mark_symbol (info, h))
|
if (! xcoff_mark_symbol (info, h))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/* If this is a function descriptor, make sure we don't garbage
|
||||||
|
collect the associated function code. We normally don't have to
|
||||||
|
worry about this, because the descriptor will be attached to a
|
||||||
|
section with relocs, but if we are creating the descriptor
|
||||||
|
ourselves those relocs will not be visible to the mark code. */
|
||||||
|
if ((h->flags & XCOFF_DESCRIPTOR) != 0)
|
||||||
|
{
|
||||||
|
if (! xcoff_mark_symbol (info, h->descriptor))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2507,7 +2606,7 @@ struct xcoff_loader_info
|
|||||||
boolean
|
boolean
|
||||||
bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
|
bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
|
||||||
file_align, maxstack, maxdata, gc,
|
file_align, maxstack, maxdata, gc,
|
||||||
modtype, textro)
|
modtype, textro, special_sections)
|
||||||
bfd *output_bfd;
|
bfd *output_bfd;
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
const char *libpath;
|
const char *libpath;
|
||||||
@ -2518,10 +2617,12 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
|
|||||||
boolean gc;
|
boolean gc;
|
||||||
int modtype;
|
int modtype;
|
||||||
boolean textro;
|
boolean textro;
|
||||||
|
asection **special_sections;
|
||||||
{
|
{
|
||||||
struct xcoff_link_hash_entry *hentry;
|
struct xcoff_link_hash_entry *hentry;
|
||||||
asection *lsec;
|
asection *lsec;
|
||||||
struct xcoff_loader_info ldinfo;
|
struct xcoff_loader_info ldinfo;
|
||||||
|
int i;
|
||||||
size_t impsize, impcount;
|
size_t impsize, impcount;
|
||||||
struct xcoff_import_file *fl;
|
struct xcoff_import_file *fl;
|
||||||
struct internal_ldhdr *ldhdr;
|
struct internal_ldhdr *ldhdr;
|
||||||
@ -2595,6 +2696,19 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
|
|||||||
xcoff_hash_table (info)->gc = true;
|
xcoff_hash_table (info)->gc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return special sections to the caller. */
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
asection *sec;
|
||||||
|
|
||||||
|
sec = xcoff_hash_table (info)->special_sections[i];
|
||||||
|
if (sec != NULL
|
||||||
|
&& gc
|
||||||
|
&& (sec->flags & SEC_MARK) == 0)
|
||||||
|
sec = NULL;
|
||||||
|
special_sections[i] = sec;
|
||||||
|
}
|
||||||
|
|
||||||
if (info->input_bfds == NULL)
|
if (info->input_bfds == NULL)
|
||||||
{
|
{
|
||||||
/* I'm not sure what to do in this bizarre case. */
|
/* I'm not sure what to do in this bizarre case. */
|
||||||
@ -2694,8 +2808,7 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
|
|||||||
when the corresponding normal relocs are handled in
|
when the corresponding normal relocs are handled in
|
||||||
xcoff_link_input_bfd. */
|
xcoff_link_input_bfd. */
|
||||||
|
|
||||||
/* Allocate space for the global linkage section and the global toc
|
/* Allocate space for the magic sections. */
|
||||||
section. */
|
|
||||||
sec = xcoff_hash_table (info)->linkage_section;
|
sec = xcoff_hash_table (info)->linkage_section;
|
||||||
if (sec->_raw_size > 0)
|
if (sec->_raw_size > 0)
|
||||||
{
|
{
|
||||||
@ -2707,6 +2820,16 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sec = xcoff_hash_table (info)->toc_section;
|
sec = xcoff_hash_table (info)->toc_section;
|
||||||
|
if (sec->_raw_size > 0)
|
||||||
|
{
|
||||||
|
sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
|
||||||
|
if (sec->contents == NULL)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_no_memory);
|
||||||
|
goto error_return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sec = xcoff_hash_table (info)->descriptor_section;
|
||||||
if (sec->_raw_size > 0)
|
if (sec->_raw_size > 0)
|
||||||
{
|
{
|
||||||
sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
|
sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
|
||||||
@ -2877,6 +3000,7 @@ xcoff_build_ldsyms (h, p)
|
|||||||
h->root.u.def.section = sec;
|
h->root.u.def.section = sec;
|
||||||
h->root.u.def.value = sec->_raw_size;
|
h->root.u.def.value = sec->_raw_size;
|
||||||
h->smclas = XMC_GL;
|
h->smclas = XMC_GL;
|
||||||
|
h->flags |= XCOFF_DEF_REGULAR;
|
||||||
sec->_raw_size += XCOFF_GLINK_SIZE;
|
sec->_raw_size += XCOFF_GLINK_SIZE;
|
||||||
|
|
||||||
/* The global linkage code requires a TOC entry for the
|
/* The global linkage code requires a TOC entry for the
|
||||||
@ -2902,6 +3026,53 @@ xcoff_build_ldsyms (h, p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If this symbol is exported, but not defined, we need to try to
|
||||||
|
define it. */
|
||||||
|
if ((h->flags & XCOFF_EXPORT) != 0
|
||||||
|
&& (h->flags & XCOFF_IMPORT) == 0
|
||||||
|
&& (h->flags & XCOFF_DEF_REGULAR) == 0
|
||||||
|
&& (h->flags & XCOFF_DEF_DYNAMIC) == 0
|
||||||
|
&& (h->root.type == bfd_link_hash_undefined
|
||||||
|
|| h->root.type == bfd_link_hash_undefweak))
|
||||||
|
{
|
||||||
|
if ((h->flags & XCOFF_DESCRIPTOR) != 0
|
||||||
|
&& (h->descriptor->root.type == bfd_link_hash_defined
|
||||||
|
|| h->descriptor->root.type == bfd_link_hash_defweak))
|
||||||
|
{
|
||||||
|
asection *sec;
|
||||||
|
|
||||||
|
/* This is an undefined function descriptor associated with
|
||||||
|
a defined entry point. We can build up a function
|
||||||
|
descriptor ourselves. Believe it or not, the AIX linker
|
||||||
|
actually does this, and there are cases where we need to
|
||||||
|
do it as well. */
|
||||||
|
sec = xcoff_hash_table (ldinfo->info)->descriptor_section;
|
||||||
|
h->root.type = bfd_link_hash_defined;
|
||||||
|
h->root.u.def.section = sec;
|
||||||
|
h->root.u.def.value = sec->_raw_size;
|
||||||
|
h->smclas = XMC_DS;
|
||||||
|
h->flags |= XCOFF_DEF_REGULAR;
|
||||||
|
sec->_raw_size += 12;
|
||||||
|
|
||||||
|
/* A function descriptor uses two relocs: one for the
|
||||||
|
associated code, and one for the TOC address. */
|
||||||
|
xcoff_hash_table (ldinfo->info)->ldrel_count += 2;
|
||||||
|
sec->reloc_count += 2;
|
||||||
|
|
||||||
|
/* We handle writing out the contents of the descriptor in
|
||||||
|
xcoff_write_global_symbol. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
("attempt to export undefined symbol `%s'",
|
||||||
|
h->root.root.string);
|
||||||
|
ldinfo->failed = true;
|
||||||
|
bfd_set_error (bfd_error_invalid_operation);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If this is still a common symbol, and it wasn't garbage
|
/* If this is still a common symbol, and it wasn't garbage
|
||||||
collected, we need to actually allocate space for it in the .bss
|
collected, we need to actually allocate space for it in the .bss
|
||||||
section. */
|
section. */
|
||||||
@ -3528,13 +3699,18 @@ _bfd_xcoff_bfd_final_link (abfd, info)
|
|||||||
o->_raw_size))
|
o->_raw_size))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
/* Write out the global linkage section and the toc section. */
|
/* Write out the magic sections. */
|
||||||
o = xcoff_hash_table (info)->linkage_section;
|
o = xcoff_hash_table (info)->linkage_section;
|
||||||
if (o->_raw_size > 0
|
if (o->_raw_size > 0
|
||||||
&& ! bfd_set_section_contents (abfd, o->output_section, o->contents,
|
&& ! bfd_set_section_contents (abfd, o->output_section, o->contents,
|
||||||
o->output_offset, o->_raw_size))
|
o->output_offset, o->_raw_size))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
o = xcoff_hash_table (info)->toc_section;
|
o = xcoff_hash_table (info)->toc_section;
|
||||||
|
if (o->_raw_size > 0
|
||||||
|
&& ! bfd_set_section_contents (abfd, o->output_section, o->contents,
|
||||||
|
o->output_offset, o->_raw_size))
|
||||||
|
goto error_return;
|
||||||
|
o = xcoff_hash_table (info)->descriptor_section;
|
||||||
if (o->_raw_size > 0
|
if (o->_raw_size > 0
|
||||||
&& ! bfd_set_section_contents (abfd, o->output_section, o->contents,
|
&& ! bfd_set_section_contents (abfd, o->output_section, o->contents,
|
||||||
o->output_offset, o->_raw_size))
|
o->output_offset, o->_raw_size))
|
||||||
@ -4857,6 +5033,109 @@ xcoff_write_global_symbol (h, p)
|
|||||||
++finfo->ldrel;
|
++finfo->ldrel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If this symbol is a specially defined function descriptor, write
|
||||||
|
it out. The first word is the address of the function code
|
||||||
|
itself, the second word is the address of the TOC, and the third
|
||||||
|
word is zero. */
|
||||||
|
if ((h->flags & XCOFF_DESCRIPTOR) != 0
|
||||||
|
&& h->root.type == bfd_link_hash_defined
|
||||||
|
&& (h->root.u.def.section
|
||||||
|
== xcoff_hash_table (finfo->info)->descriptor_section))
|
||||||
|
{
|
||||||
|
asection *sec;
|
||||||
|
asection *osec;
|
||||||
|
int oindx;
|
||||||
|
bfd_byte *p;
|
||||||
|
struct xcoff_link_hash_entry *hentry;
|
||||||
|
asection *esec;
|
||||||
|
struct internal_reloc *irel;
|
||||||
|
struct internal_ldrel ldrel;
|
||||||
|
asection *tsec;
|
||||||
|
|
||||||
|
sec = h->root.u.def.section;
|
||||||
|
osec = sec->output_section;
|
||||||
|
oindx = osec->target_index;
|
||||||
|
p = sec->contents + h->root.u.def.value;
|
||||||
|
|
||||||
|
hentry = h->descriptor;
|
||||||
|
BFD_ASSERT (hentry != NULL
|
||||||
|
&& (hentry->root.type == bfd_link_hash_defined
|
||||||
|
|| hentry->root.type == bfd_link_hash_defweak));
|
||||||
|
esec = hentry->root.u.def.section;
|
||||||
|
bfd_put_32 (output_bfd,
|
||||||
|
(esec->output_section->vma
|
||||||
|
+ esec->output_offset
|
||||||
|
+ hentry->root.u.def.value),
|
||||||
|
p);
|
||||||
|
|
||||||
|
irel = finfo->section_info[oindx].relocs + osec->reloc_count;
|
||||||
|
irel->r_vaddr = (osec->vma
|
||||||
|
+ sec->output_offset
|
||||||
|
+ h->root.u.def.value);
|
||||||
|
irel->r_symndx = esec->output_section->target_index;
|
||||||
|
irel->r_type = R_POS;
|
||||||
|
irel->r_size = 31;
|
||||||
|
finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
|
||||||
|
++osec->reloc_count;
|
||||||
|
|
||||||
|
ldrel.l_vaddr = irel->r_vaddr;
|
||||||
|
if (strcmp (esec->output_section->name, ".text") == 0)
|
||||||
|
ldrel.l_symndx = 0;
|
||||||
|
else if (strcmp (esec->output_section->name, ".data") == 0)
|
||||||
|
ldrel.l_symndx = 1;
|
||||||
|
else if (strcmp (esec->output_section->name, ".bss") == 0)
|
||||||
|
ldrel.l_symndx = 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
("%s: loader reloc in unrecognized section `%s'",
|
||||||
|
bfd_get_filename (output_bfd),
|
||||||
|
esec->output_section->name);
|
||||||
|
bfd_set_error (bfd_error_nonrepresentable_section);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ldrel.l_rtype = (31 << 8) | R_POS;
|
||||||
|
ldrel.l_rsecnm = oindx;
|
||||||
|
xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel);
|
||||||
|
++finfo->ldrel;
|
||||||
|
|
||||||
|
bfd_put_32 (output_bfd, xcoff_data (output_bfd)->toc, p + 4);
|
||||||
|
|
||||||
|
tsec = xcoff_data (output_bfd)->toc_section;
|
||||||
|
|
||||||
|
++irel;
|
||||||
|
irel->r_vaddr = (osec->vma
|
||||||
|
+ sec->output_offset
|
||||||
|
+ h->root.u.def.value
|
||||||
|
+ 4);
|
||||||
|
irel->r_symndx = tsec->output_section->target_index;
|
||||||
|
irel->r_type = R_POS;
|
||||||
|
irel->r_size = 31;
|
||||||
|
finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
|
||||||
|
++osec->reloc_count;
|
||||||
|
|
||||||
|
ldrel.l_vaddr = irel->r_vaddr;
|
||||||
|
if (strcmp (tsec->output_section->name, ".text") == 0)
|
||||||
|
ldrel.l_symndx = 0;
|
||||||
|
else if (strcmp (tsec->output_section->name, ".data") == 0)
|
||||||
|
ldrel.l_symndx = 1;
|
||||||
|
else if (strcmp (tsec->output_section->name, ".bss") == 0)
|
||||||
|
ldrel.l_symndx = 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
("%s: loader reloc in unrecognized section `%s'",
|
||||||
|
bfd_get_filename (output_bfd),
|
||||||
|
tsec->output_section->name);
|
||||||
|
bfd_set_error (bfd_error_nonrepresentable_section);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ldrel.l_rtype = (31 << 8) | R_POS;
|
||||||
|
ldrel.l_rsecnm = oindx;
|
||||||
|
xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel);
|
||||||
|
++finfo->ldrel;
|
||||||
|
}
|
||||||
|
|
||||||
if (h->indx >= 0)
|
if (h->indx >= 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user