mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-24 18:35:28 +00:00
include/coff/
* xcoff.h (XCOFF_CALLED, XCOFF_IMPORT): Update comments. (XCOFF_WAS_UNDEFINED): New flag. (xcoff_link_hash_table): Add an "rtld" field. bfd/ * coff-rs6000.c (xcoff_ppc_relocate_section): Report relocations against undefined symbols if the symbol's XCOFF_WAS_UNDEFINED flag is set. Assert that all undefined symbols are either imported or defined by a dynamic object. * coff64-rs6000.c (xcoff64_ppc_relocate_section): Likewise. * xcofflink.c (xcoff_link_add_symbols): Extend function-symbol handling to all relocations. Only set XCOFF_CALLED for function symbols. (xcoff_find_function): New function, split out from... (bfd_xcoff_export_symbol) ...here. (xcoff_set_import_path): New function, split out from... (bfd_xcoff_import_symbol): ...here. Remove assertion for old meaning of XCOFF_CALLED. (xcoff_mark_symbol): If we mark an undefined and unimported symbol, find some way of defining it. If the symbol is a function descriptor, fill in its definition automatically. If the symbol is a function, mark its descriptor and allocate room for global linkage code. Otherwise mark the symbol as implicitly imported. Move the code for creating function descriptors from... (xcoff_build_ldsyms): ...here. Use XCOFF_WAS_UNDEFINED to check for symbols that were implicitly defined. (xcoff_mark): Don't count any dynamic relocations against function symbols. (bfd_xcoff_size_dynamic_sections): Save the rtld parameter in the xcoff link info. (xcoff_link_input_bfd): Remove handling of undefined and unexported symbols. ld/ * emultempl/aix.em (gld${EMULATION_NAME}_handle_option): Make -berok and -bernotok control link_info.unresolved_syms_in_objects and link_info.unresolved_syms_in_shared_libs instead of force_make_executable. ld/testsuite/ * ld-powerpc/aix-glink-1.ex, ld-powerpc/aix-glink-1.s, ld-powerpc/aix-glink-1-32.dd, ld-powerpc/aix-glink-1-64.dd, ld-powerpc/aix-glink-1-32.d, ld-powerpc/aix-glink-1-64.d: New tests. * ld-powerpc/aix52.exp: Run them.
This commit is contained in:
parent
9f0eb2327b
commit
858ef0ce3b
@ -1,3 +1,33 @@
|
||||
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* coff-rs6000.c (xcoff_ppc_relocate_section): Report relocations
|
||||
against undefined symbols if the symbol's XCOFF_WAS_UNDEFINED
|
||||
flag is set. Assert that all undefined symbols are either
|
||||
imported or defined by a dynamic object.
|
||||
* coff64-rs6000.c (xcoff64_ppc_relocate_section): Likewise.
|
||||
* xcofflink.c (xcoff_link_add_symbols): Extend function-symbol
|
||||
handling to all relocations. Only set XCOFF_CALLED for function
|
||||
symbols.
|
||||
(xcoff_find_function): New function, split out from...
|
||||
(bfd_xcoff_export_symbol) ...here.
|
||||
(xcoff_set_import_path): New function, split out from...
|
||||
(bfd_xcoff_import_symbol): ...here. Remove assertion for old
|
||||
meaning of XCOFF_CALLED.
|
||||
(xcoff_mark_symbol): If we mark an undefined and unimported
|
||||
symbol, find some way of defining it. If the symbol is a function
|
||||
descriptor, fill in its definition automatically. If the symbol
|
||||
is a function, mark its descriptor and allocate room for global
|
||||
linkage code. Otherwise mark the symbol as implicitly imported.
|
||||
Move the code for creating function descriptors from...
|
||||
(xcoff_build_ldsyms): ...here. Use XCOFF_WAS_UNDEFINED to
|
||||
check for symbols that were implicitly defined.
|
||||
(xcoff_mark): Don't count any dynamic relocations against
|
||||
function symbols.
|
||||
(bfd_xcoff_size_dynamic_sections): Save the rtld parameter
|
||||
in the xcoff link info.
|
||||
(xcoff_link_input_bfd): Remove handling of undefined and
|
||||
unexported symbols.
|
||||
|
||||
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* coff-rs6000.c (xcoff_reloc_type_br): Make the branch absolute
|
||||
|
@ -3447,6 +3447,17 @@ xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->unresolved_syms_in_objects != RM_IGNORE
|
||||
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string,
|
||||
input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma,
|
||||
(info->unresolved_syms_in_objects
|
||||
== RM_GENERATE_ERROR))))
|
||||
return FALSE;
|
||||
}
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
@ -3462,17 +3473,11 @@ xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
|
||||
+ sec->output_offset);
|
||||
|
||||
}
|
||||
else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
|
||||
&& ! info->relocatable)
|
||||
else
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma, TRUE)))
|
||||
return FALSE;
|
||||
|
||||
/* Don't try to process the reloc. It can't help, and
|
||||
it may generate another error. */
|
||||
continue;
|
||||
BFD_ASSERT (info->relocatable
|
||||
|| (h->flags & XCOFF_DEF_DYNAMIC) != 0
|
||||
|| (h->flags & XCOFF_IMPORT) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1293,6 +1293,17 @@ xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->unresolved_syms_in_objects != RM_IGNORE
|
||||
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string,
|
||||
input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma,
|
||||
(info->unresolved_syms_in_objects
|
||||
== RM_GENERATE_ERROR))))
|
||||
return FALSE;
|
||||
}
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
@ -1307,17 +1318,11 @@ xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
|
||||
&& ! info->relocatable)
|
||||
else
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma, TRUE)))
|
||||
return FALSE;
|
||||
|
||||
/* Don't try to process the reloc. It can't help, and
|
||||
it may generate another error. */
|
||||
continue;
|
||||
BFD_ASSERT (info->relocatable
|
||||
|| (h->flags & XCOFF_DEF_DYNAMIC) != 0
|
||||
|| (h->flags & XCOFF_IMPORT) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
446
bfd/xcofflink.c
446
bfd/xcofflink.c
@ -1845,19 +1845,16 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* We identify all symbols which are called, so that we
|
||||
can create glue code for calls to functions imported
|
||||
from dynamic objects. */
|
||||
/* We identify all function symbols that are the target
|
||||
of a relocation, so that we can create glue code for
|
||||
functions imported from dynamic objects. */
|
||||
if (info->output_bfd->xvec == abfd->xvec
|
||||
&& *rel_csect != bfd_und_section_ptr
|
||||
&& (rel->r_type == R_BR
|
||||
|| rel->r_type == R_RBR)
|
||||
&& obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL)
|
||||
{
|
||||
struct xcoff_link_hash_entry *h;
|
||||
|
||||
h = obj_xcoff_sym_hashes (abfd)[rel->r_symndx];
|
||||
h->flags |= XCOFF_CALLED;
|
||||
/* If the symbol name starts with a period, it is
|
||||
the code of a function. If the symbol is
|
||||
currently undefined, then add an undefined symbol
|
||||
@ -1890,11 +1887,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
hds = (struct xcoff_link_hash_entry *) bh;
|
||||
}
|
||||
hds->flags |= XCOFF_DESCRIPTOR;
|
||||
BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0
|
||||
&& (h->flags & XCOFF_DESCRIPTOR) == 0);
|
||||
BFD_ASSERT ((h->flags & XCOFF_DESCRIPTOR) == 0);
|
||||
hds->descriptor = h;
|
||||
h->descriptor = hds;
|
||||
}
|
||||
if (h->root.root.string[0] == '.')
|
||||
h->flags |= XCOFF_CALLED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2203,6 +2201,94 @@ _bfd_xcoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
/* If symbol H has not been interpreted as a function descriptor,
|
||||
see whether it should be. Set up its descriptor information if so. */
|
||||
|
||||
static bfd_boolean
|
||||
xcoff_find_function (struct bfd_link_info *info,
|
||||
struct xcoff_link_hash_entry *h)
|
||||
{
|
||||
if ((h->flags & XCOFF_DESCRIPTOR) == 0
|
||||
&& h->root.root.string[0] != '.')
|
||||
{
|
||||
char *fnname;
|
||||
struct xcoff_link_hash_entry *hfn;
|
||||
bfd_size_type amt;
|
||||
|
||||
amt = strlen (h->root.root.string) + 2;
|
||||
fnname = bfd_malloc (amt);
|
||||
if (fnname == NULL)
|
||||
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;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* H is an imported symbol. Set the import module's path, file and member
|
||||
to IMPATH, IMPFILE and IMPMEMBER respectively. All three are null if
|
||||
no specific import module is specified. */
|
||||
|
||||
static bfd_boolean
|
||||
xcoff_set_import_path (struct bfd_link_info *info,
|
||||
struct xcoff_link_hash_entry *h,
|
||||
const char *imppath, const char *impfile,
|
||||
const char *impmember)
|
||||
{
|
||||
unsigned int c;
|
||||
struct xcoff_import_file **pp;
|
||||
|
||||
/* We overload the ldindx field to hold the l_ifile value for this
|
||||
symbol. */
|
||||
BFD_ASSERT (h->ldsym == NULL);
|
||||
BFD_ASSERT ((h->flags & XCOFF_BUILT_LDSYM) == 0);
|
||||
if (imppath == NULL)
|
||||
h->ldindx = -1;
|
||||
else
|
||||
{
|
||||
/* We start c at 1 because the first entry in the import list is
|
||||
reserved for the library search path. */
|
||||
for (pp = &xcoff_hash_table (info)->imports, c = 1;
|
||||
*pp != NULL;
|
||||
pp = &(*pp)->next, ++c)
|
||||
{
|
||||
if (strcmp ((*pp)->path, imppath) == 0
|
||||
&& strcmp ((*pp)->file, impfile) == 0
|
||||
&& strcmp ((*pp)->member, impmember) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (*pp == NULL)
|
||||
{
|
||||
struct xcoff_import_file *n;
|
||||
bfd_size_type amt = sizeof (* n);
|
||||
|
||||
n = bfd_alloc (info->output_bfd, amt);
|
||||
if (n == NULL)
|
||||
return FALSE;
|
||||
n->next = NULL;
|
||||
n->path = imppath;
|
||||
n->file = impfile;
|
||||
n->member = impmember;
|
||||
*pp = n;
|
||||
}
|
||||
h->ldindx = c;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Mark a symbol as not being garbage, including the section in which
|
||||
it is defined. */
|
||||
|
||||
@ -2213,6 +2299,136 @@ xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h)
|
||||
return TRUE;
|
||||
|
||||
h->flags |= XCOFF_MARK;
|
||||
|
||||
/* If we're marking an undefined symbol, try find some way of
|
||||
defining it. */
|
||||
if (!info->relocatable
|
||||
&& (h->flags & XCOFF_IMPORT) == 0
|
||||
&& (h->flags & XCOFF_DEF_REGULAR) == 0
|
||||
&& (h->root.type == bfd_link_hash_undefined
|
||||
|| h->root.type == bfd_link_hash_undefweak))
|
||||
{
|
||||
/* First check whether this symbol can be interpreted as an
|
||||
undefined function descriptor for a defined function symbol. */
|
||||
if (!xcoff_find_function (info, h))
|
||||
return FALSE;
|
||||
|
||||
if ((h->flags & XCOFF_DESCRIPTOR) != 0
|
||||
&& (h->descriptor->root.type == bfd_link_hash_defined
|
||||
|| h->descriptor->root.type == bfd_link_hash_defweak))
|
||||
{
|
||||
/* This is a descriptor for a defined symbol, but the input
|
||||
objects have not defined the descriptor itself. Fill in
|
||||
the definition automatically.
|
||||
|
||||
Note that we do this even if we found a dynamic definition
|
||||
of H. The local function definition logically overrides
|
||||
the dynamic one. */
|
||||
asection *sec;
|
||||
|
||||
sec = xcoff_hash_table (info)->descriptor_section;
|
||||
h->root.type = bfd_link_hash_defined;
|
||||
h->root.u.def.section = sec;
|
||||
h->root.u.def.value = sec->size;
|
||||
h->smclas = XMC_DS;
|
||||
h->flags |= XCOFF_DEF_REGULAR;
|
||||
|
||||
/* The size of the function descriptor depends on whether this
|
||||
is xcoff32 (12) or xcoff64 (24). */
|
||||
sec->size += bfd_xcoff_function_descriptor_size (sec->owner);
|
||||
|
||||
/* A function descriptor uses two relocs: one for the
|
||||
associated code, and one for the TOC address. */
|
||||
xcoff_hash_table (info)->ldrel_count += 2;
|
||||
sec->reloc_count += 2;
|
||||
|
||||
/* Mark the function itself. */
|
||||
if (!xcoff_mark_symbol (info, h->descriptor))
|
||||
return FALSE;
|
||||
|
||||
/* We handle writing out the contents of the descriptor in
|
||||
xcoff_write_global_symbol. */
|
||||
}
|
||||
else if ((h->flags & XCOFF_CALLED) != 0)
|
||||
{
|
||||
/* This is a function symbol for which we need to create
|
||||
linkage code. */
|
||||
asection *sec;
|
||||
struct xcoff_link_hash_entry *hds;
|
||||
|
||||
/* Mark the descriptor (and its TOC section). */
|
||||
hds = h->descriptor;
|
||||
BFD_ASSERT ((hds->root.type == bfd_link_hash_undefined
|
||||
|| hds->root.type == bfd_link_hash_undefweak)
|
||||
&& (hds->flags & XCOFF_DEF_REGULAR) == 0);
|
||||
if (!xcoff_mark_symbol (info, hds))
|
||||
return FALSE;
|
||||
|
||||
/* Treat this symbol as undefined if the descriptor was. */
|
||||
if ((hds->flags & XCOFF_WAS_UNDEFINED) != 0)
|
||||
h->flags |= XCOFF_WAS_UNDEFINED;
|
||||
|
||||
/* Allocate room for the global linkage code itself. */
|
||||
sec = xcoff_hash_table (info)->linkage_section;
|
||||
h->root.type = bfd_link_hash_defined;
|
||||
h->root.u.def.section = sec;
|
||||
h->root.u.def.value = sec->size;
|
||||
h->smclas = XMC_GL;
|
||||
h->flags |= XCOFF_DEF_REGULAR;
|
||||
sec->size += bfd_xcoff_glink_code_size (info->output_bfd);
|
||||
|
||||
/* The global linkage code requires a TOC entry for the
|
||||
descriptor. */
|
||||
if (hds->toc_section == NULL)
|
||||
{
|
||||
int byte_size;
|
||||
|
||||
/* 32 vs 64
|
||||
xcoff32 uses 4 bytes in the toc.
|
||||
xcoff64 uses 8 bytes in the toc. */
|
||||
if (bfd_xcoff_is_xcoff64 (info->output_bfd))
|
||||
byte_size = 8;
|
||||
else if (bfd_xcoff_is_xcoff32 (info->output_bfd))
|
||||
byte_size = 4;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
/* Allocate room in the fallback TOC section. */
|
||||
hds->toc_section = xcoff_hash_table (info)->toc_section;
|
||||
hds->u.toc_offset = hds->toc_section->size;
|
||||
hds->toc_section->size += byte_size;
|
||||
if (!xcoff_mark (info, hds->toc_section))
|
||||
return FALSE;
|
||||
|
||||
/* Allocate room for a static and dynamic R_TOC
|
||||
relocation. */
|
||||
++xcoff_hash_table (info)->ldrel_count;
|
||||
++hds->toc_section->reloc_count;
|
||||
|
||||
/* Set the index to -2 to force this symbol to
|
||||
get written out. */
|
||||
hds->indx = -2;
|
||||
hds->flags |= XCOFF_SET_TOC | XCOFF_LDREL;
|
||||
}
|
||||
}
|
||||
else if ((h->flags & XCOFF_DEF_DYNAMIC) == 0)
|
||||
{
|
||||
/* Record that the symbol was undefined, then import it.
|
||||
-brtl links use a special fake import file. */
|
||||
h->flags |= XCOFF_WAS_UNDEFINED | XCOFF_IMPORT;
|
||||
if (xcoff_hash_table (info)->rtld)
|
||||
{
|
||||
if (!xcoff_set_import_path (info, h, "", "..", ""))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!xcoff_set_import_path (info, h, NULL, NULL, NULL))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
@ -2320,15 +2536,9 @@ xcoff_mark (struct bfd_link_info *info, asection *sec)
|
||||
|| h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak
|
||||
|| h->root.type == bfd_link_hash_common
|
||||
|| ((h->flags & XCOFF_CALLED) != 0
|
||||
&& (h->root.type == bfd_link_hash_undefined
|
||||
|| h->root.type == bfd_link_hash_undefweak)
|
||||
&& h->root.root.string[0] == '.'
|
||||
&& h->descriptor != NULL
|
||||
&& ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0
|
||||
|| ((h->descriptor->flags & XCOFF_IMPORT) != 0
|
||||
&& (h->descriptor->flags
|
||||
& XCOFF_DEF_REGULAR) == 0))))
|
||||
/* We will always provide a local definition of
|
||||
function symbols. */
|
||||
|| (h->flags & XCOFF_CALLED) != 0)
|
||||
break;
|
||||
/* Fall through. */
|
||||
case R_POS:
|
||||
@ -2483,8 +2693,7 @@ bfd_xcoff_import_symbol (bfd *output_bfd,
|
||||
hds->root.u.undef.abfd = h->root.u.undef.abfd;
|
||||
}
|
||||
hds->flags |= XCOFF_DESCRIPTOR;
|
||||
BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0
|
||||
&& (h->flags & XCOFF_DESCRIPTOR) == 0);
|
||||
BFD_ASSERT ((h->flags & XCOFF_DESCRIPTOR) == 0);
|
||||
hds->descriptor = h;
|
||||
h->descriptor = hds;
|
||||
}
|
||||
@ -2516,46 +2725,8 @@ bfd_xcoff_import_symbol (bfd *output_bfd,
|
||||
h->root.u.def.value = val;
|
||||
}
|
||||
|
||||
/* We overload the ldindx field to hold the l_ifile value for this
|
||||
symbol. */
|
||||
BFD_ASSERT (h->ldsym == NULL);
|
||||
BFD_ASSERT ((h->flags & XCOFF_BUILT_LDSYM) == 0);
|
||||
if (imppath == NULL)
|
||||
h->ldindx = -1;
|
||||
else
|
||||
{
|
||||
unsigned int c;
|
||||
struct xcoff_import_file **pp;
|
||||
|
||||
/* We start c at 1 because the first entry in the import list is
|
||||
reserved for the library search path. */
|
||||
for (pp = &xcoff_hash_table (info)->imports, c = 1;
|
||||
*pp != NULL;
|
||||
pp = &(*pp)->next, ++c)
|
||||
{
|
||||
if (strcmp ((*pp)->path, imppath) == 0
|
||||
&& strcmp ((*pp)->file, impfile) == 0
|
||||
&& strcmp ((*pp)->member, impmember) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (*pp == NULL)
|
||||
{
|
||||
struct xcoff_import_file *n;
|
||||
bfd_size_type amt = sizeof (* n);
|
||||
|
||||
n = bfd_alloc (output_bfd, amt);
|
||||
if (n == NULL)
|
||||
return FALSE;
|
||||
n->next = NULL;
|
||||
n->path = imppath;
|
||||
n->file = impfile;
|
||||
n->member = impmember;
|
||||
*pp = n;
|
||||
}
|
||||
|
||||
h->ldindx = c;
|
||||
}
|
||||
if (!xcoff_set_import_path (info, h, imppath, impfile, impmember))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -2577,34 +2748,6 @@ bfd_xcoff_export_symbol (bfd *output_bfd,
|
||||
/* 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. */
|
||||
|
||||
/* 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;
|
||||
bfd_size_type amt = strlen (h->root.root.string) + 2;
|
||||
|
||||
fnname = bfd_malloc (amt);
|
||||
if (fnname == NULL)
|
||||
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. */
|
||||
if (! xcoff_mark_symbol (info, h))
|
||||
return FALSE;
|
||||
@ -2767,115 +2910,16 @@ xcoff_build_ldsyms (struct xcoff_link_hash_entry *h, void * p)
|
||||
!= ldinfo->info->output_bfd->xvec)))
|
||||
h->flags |= XCOFF_MARK;
|
||||
|
||||
/* If this symbol is called and defined in a dynamic object, or it
|
||||
is imported, then we need to set up global linkage code for it.
|
||||
(Unless we did garbage collection and we didn't need this
|
||||
symbol.) */
|
||||
if ((h->flags & XCOFF_CALLED) != 0
|
||||
&& (h->root.type == bfd_link_hash_undefined
|
||||
|| h->root.type == bfd_link_hash_undefweak)
|
||||
&& h->root.root.string[0] == '.'
|
||||
&& h->descriptor != NULL
|
||||
&& ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0
|
||||
|| ((h->descriptor->flags & XCOFF_IMPORT) != 0
|
||||
&& (h->descriptor->flags & XCOFF_DEF_REGULAR) == 0))
|
||||
&& (! xcoff_hash_table (ldinfo->info)->gc
|
||||
|| (h->flags & XCOFF_MARK) != 0))
|
||||
{
|
||||
asection *sec;
|
||||
struct xcoff_link_hash_entry *hds;
|
||||
|
||||
sec = xcoff_hash_table (ldinfo->info)->linkage_section;
|
||||
h->root.type = bfd_link_hash_defined;
|
||||
h->root.u.def.section = sec;
|
||||
h->root.u.def.value = sec->size;
|
||||
h->smclas = XMC_GL;
|
||||
h->flags |= XCOFF_DEF_REGULAR;
|
||||
sec->size += bfd_xcoff_glink_code_size(ldinfo->output_bfd);
|
||||
|
||||
/* The global linkage code requires a TOC entry for the
|
||||
descriptor. */
|
||||
hds = h->descriptor;
|
||||
BFD_ASSERT ((hds->root.type == bfd_link_hash_undefined
|
||||
|| hds->root.type == bfd_link_hash_undefweak)
|
||||
&& (hds->flags & XCOFF_DEF_REGULAR) == 0);
|
||||
hds->flags |= XCOFF_MARK;
|
||||
if (hds->toc_section == NULL)
|
||||
{
|
||||
int byte_size;
|
||||
|
||||
/* 32 vs 64
|
||||
xcoff32 uses 4 bytes in the toc.
|
||||
xcoff64 uses 8 bytes in the toc. */
|
||||
if (bfd_xcoff_is_xcoff64 (ldinfo->output_bfd))
|
||||
byte_size = 8;
|
||||
else if (bfd_xcoff_is_xcoff32 (ldinfo->output_bfd))
|
||||
byte_size = 4;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section;
|
||||
hds->u.toc_offset = hds->toc_section->size;
|
||||
hds->toc_section->size += byte_size;
|
||||
++xcoff_hash_table (ldinfo->info)->ldrel_count;
|
||||
++hds->toc_section->reloc_count;
|
||||
hds->indx = -2;
|
||||
hds->flags |= XCOFF_SET_TOC | XCOFF_LDREL;
|
||||
|
||||
/* We need to call xcoff_build_ldsyms recursively here,
|
||||
because we may already have passed hds on the traversal. */
|
||||
xcoff_build_ldsyms (hds, 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))
|
||||
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
|
||||
{
|
||||
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->size;
|
||||
h->smclas = XMC_DS;
|
||||
h->flags |= XCOFF_DEF_REGULAR;
|
||||
|
||||
/* The size of the function descriptor depends if this is an
|
||||
xcoff32 (12) or xcoff64 (24). */
|
||||
sec->size +=
|
||||
bfd_xcoff_function_descriptor_size(ldinfo->output_bfd);
|
||||
|
||||
/* 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)
|
||||
(_("warning: attempt to export undefined symbol `%s'"),
|
||||
h->root.root.string);
|
||||
h->ldsym = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
(*_bfd_error_handler)
|
||||
(_("warning: attempt to export undefined symbol `%s'"),
|
||||
h->root.root.string);
|
||||
h->ldsym = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If this is still a common symbol, and it wasn't garbage
|
||||
@ -3017,6 +3061,7 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
|
||||
|
||||
xcoff_hash_table (info)->file_align = file_align;
|
||||
xcoff_hash_table (info)->textro = textro;
|
||||
xcoff_hash_table (info)->rtld = rtld;
|
||||
|
||||
hentry = NULL;
|
||||
if (entry != NULL)
|
||||
@ -4318,7 +4363,6 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
|
||||
{
|
||||
struct xcoff_link_hash_entry *h = NULL;
|
||||
struct internal_ldrel ldrel;
|
||||
bfd_boolean quiet;
|
||||
|
||||
*rel_hash = NULL;
|
||||
|
||||
@ -4451,7 +4495,6 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
|
||||
}
|
||||
}
|
||||
|
||||
quiet = FALSE;
|
||||
switch (irel->r_type)
|
||||
{
|
||||
default:
|
||||
@ -4507,17 +4550,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! finfo->info->relocatable
|
||||
&& (h->flags & XCOFF_DEF_DYNAMIC) == 0
|
||||
&& (h->flags & XCOFF_IMPORT) == 0)
|
||||
{
|
||||
/* We already called the undefined_symbol
|
||||
callback for this relocation, in
|
||||
_bfd_ppc_xcoff_relocate_section. Don't
|
||||
issue any more warnings. */
|
||||
quiet = TRUE;
|
||||
}
|
||||
if (h->ldindx < 0 && ! quiet)
|
||||
if (h->ldindx < 0)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: `%s' in loader reloc but not loader sym"),
|
||||
@ -4531,8 +4564,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
|
||||
ldrel.l_rtype = (irel->r_size << 8) | irel->r_type;
|
||||
ldrel.l_rsecnm = o->output_section->target_index;
|
||||
if (xcoff_hash_table (finfo->info)->textro
|
||||
&& strcmp (o->output_section->name, ".text") == 0
|
||||
&& ! quiet)
|
||||
&& strcmp (o->output_section->name, ".text") == 0)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: loader reloc in read-only section %A"),
|
||||
|
@ -1,3 +1,9 @@
|
||||
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* xcoff.h (XCOFF_CALLED, XCOFF_IMPORT): Update comments.
|
||||
(XCOFF_WAS_UNDEFINED): New flag.
|
||||
(xcoff_link_hash_table): Add an "rtld" field.
|
||||
|
||||
2008-12-23 Johan Olmutz Nielsen <jnielsen@ddci.com>
|
||||
|
||||
* ti.h (COFF_ADJUST_SCNHDR_OUT_PRE): Define.
|
||||
|
@ -291,11 +291,12 @@ struct xcoff_link_hash_entry
|
||||
#define XCOFF_LDREL 0x00000008
|
||||
/* Symbol is the entry point. */
|
||||
#define XCOFF_ENTRY 0x00000010
|
||||
/* Symbol is called; this is, it appears in a R_BR reloc. */
|
||||
/* Symbol is for a function and is the target of a relocation.
|
||||
The relocation may or may not be a branch-type relocation. */
|
||||
#define XCOFF_CALLED 0x00000020
|
||||
/* Symbol needs the TOC entry filled in. */
|
||||
#define XCOFF_SET_TOC 0x00000040
|
||||
/* Symbol is explicitly imported. */
|
||||
/* Symbol is implicitly or explicitly imported. */
|
||||
#define XCOFF_IMPORT 0x00000080
|
||||
/* Symbol is explicitly exported. */
|
||||
#define XCOFF_EXPORT 0x00000100
|
||||
@ -315,6 +316,8 @@ struct xcoff_link_hash_entry
|
||||
#define XCOFF_SYSCALL32 0x00008000
|
||||
/* Symbol is an imported 64 bit syscall. */
|
||||
#define XCOFF_SYSCALL64 0x00010000
|
||||
/* Symbol was not explicitly defined by the time it was marked. */
|
||||
#define XCOFF_WAS_UNDEFINED 0x00020000
|
||||
|
||||
/* The XCOFF linker hash table. */
|
||||
|
||||
@ -368,6 +371,9 @@ struct xcoff_link_hash_table
|
||||
/* Whether the .text section must be read-only. */
|
||||
bfd_boolean textro;
|
||||
|
||||
/* Whether -brtl was specified. */
|
||||
bfd_boolean rtld;
|
||||
|
||||
/* Whether garbage collection was done. */
|
||||
bfd_boolean gc;
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* emultempl/aix.em (gld${EMULATION_NAME}_handle_option): Make
|
||||
-berok and -bernotok control link_info.unresolved_syms_in_objects
|
||||
and link_info.unresolved_syms_in_shared_libs instead of
|
||||
force_make_executable.
|
||||
|
||||
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* emultempl/aix.em (gld${EMULATION_NAME}_before_parse): Set
|
||||
|
@ -379,11 +379,13 @@ gld${EMULATION_NAME}_handle_option (int optc)
|
||||
break;
|
||||
|
||||
case OPTION_ERNOTOK:
|
||||
force_make_executable = FALSE;
|
||||
link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
|
||||
link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
|
||||
break;
|
||||
|
||||
case OPTION_EROK:
|
||||
force_make_executable = TRUE;
|
||||
link_info.unresolved_syms_in_objects = RM_IGNORE;
|
||||
link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
|
||||
break;
|
||||
|
||||
case OPTION_EXPORT:
|
||||
|
@ -1,3 +1,10 @@
|
||||
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* ld-powerpc/aix-glink-1.ex, ld-powerpc/aix-glink-1.s,
|
||||
ld-powerpc/aix-glink-1-32.dd, ld-powerpc/aix-glink-1-64.dd,
|
||||
ld-powerpc/aix-glink-1-32.d, ld-powerpc/aix-glink-1-64.d: New tests.
|
||||
* ld-powerpc/aix52.exp: Run them.
|
||||
|
||||
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* ld-powerpc/aix-abs-branch-1.im, ld-powerpc/aix-abs-branch-1.ex,
|
||||
|
5
ld/testsuite/ld-powerpc/aix-glink-1-32.d
Normal file
5
ld/testsuite/ld-powerpc/aix-glink-1-32.d
Normal file
@ -0,0 +1,5 @@
|
||||
#name: Glink test 1 (error) (32-bit)
|
||||
#source: aix-glink-1.s
|
||||
#as: -a32
|
||||
#ld: -b32 -bM:SRE -bnogc
|
||||
#error: undefined reference to `\.ext'
|
44
ld/testsuite/ld-powerpc/aix-glink-1-32.dd
Normal file
44
ld/testsuite/ld-powerpc/aix-glink-1-32.dd
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
.*
|
||||
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
10000000 <\.f1>:
|
||||
10000000: 4e 80 00 20 br
|
||||
|
||||
10000004 <\.f2>:
|
||||
10000004: 48 00 00 05 bl 10000008 <\.f3>
|
||||
|
||||
10000008 <\.f3>:
|
||||
10000008: 4e 80 00 20 br
|
||||
|
||||
1000000c <\.ext>:
|
||||
1000000c: 81 82 00 00 l r12,0\(r2\)
|
||||
10000010: 90 41 00 14 st r2,20\(r1\)
|
||||
10000014: 80 0c 00 00 l r0,0\(r12\)
|
||||
10000018: 80 4c 00 04 l r2,4\(r12\)
|
||||
1000001c: 7c 09 03 a6 mtctr r0
|
||||
10000020: 4e 80 04 20 bctr
|
||||
10000024: 00 00 00 00 \.long 0x0
|
||||
10000028: 00 0c 80 00 \.long 0xc8000
|
||||
1000002c: 00 00 00 00 \.long 0x0
|
||||
|
||||
Disassembly of section \.data:
|
||||
|
||||
20000000 <foo>:
|
||||
20000000: 20 00 00 08 .*
|
||||
20000004: 10 00 00 0c .*
|
||||
|
||||
20000008 <f1>:
|
||||
20000008: 10 00 00 00 .*
|
||||
2000000c: 20 00 00 20 .*
|
||||
20000010: 00 00 00 00 .*
|
||||
|
||||
20000014 <f2>:
|
||||
20000014: 10 00 00 04 .*
|
||||
20000018: 20 00 00 20 .*
|
||||
2000001c: 00 00 00 00 .*
|
||||
|
||||
20000020 <TOC>:
|
||||
\.\.\.
|
5
ld/testsuite/ld-powerpc/aix-glink-1-64.d
Normal file
5
ld/testsuite/ld-powerpc/aix-glink-1-64.d
Normal file
@ -0,0 +1,5 @@
|
||||
#name: Glink test 1 (error) (64-bit)
|
||||
#source: aix-glink-1.s
|
||||
#as: -a64
|
||||
#ld: -b64 -bM:SRE -bnogc
|
||||
#error: undefined reference to `\.ext'
|
49
ld/testsuite/ld-powerpc/aix-glink-1-64.dd
Normal file
49
ld/testsuite/ld-powerpc/aix-glink-1-64.dd
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
.*
|
||||
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0000000010000000 <\.f1>:
|
||||
10000000: 4e 80 00 20 blr
|
||||
|
||||
0000000010000004 <\.f2>:
|
||||
10000004: 48 00 00 05 bl 10000008 <\.f3>
|
||||
|
||||
0000000010000008 <\.f3>:
|
||||
10000008: 4e 80 00 20 blr
|
||||
|
||||
000000001000000c <\.ext>:
|
||||
1000000c: e9 82 00 00 ld r12,0\(r2\)
|
||||
10000010: f8 41 00 28 std r2,40\(r1\)
|
||||
10000014: e8 0c 00 00 ld r0,0\(r12\)
|
||||
10000018: e8 4c 00 08 ld r2,8\(r12\)
|
||||
1000001c: 7c 09 03 a6 mtctr r0
|
||||
10000020: 4e 80 04 20 bctr
|
||||
10000024: 00 00 00 00 \.long 0x0
|
||||
10000028: 00 0c a0 00 \.long 0xca000
|
||||
1000002c: 00 00 00 00 \.long 0x0
|
||||
10000030: 00 00 00 18 \.long 0x18
|
||||
|
||||
Disassembly of section \.data:
|
||||
|
||||
0000000020000000 <foo>:
|
||||
20000000: 20 00 00 08 .*
|
||||
20000004: 10 00 00 0c .*
|
||||
|
||||
0000000020000008 <f1>:
|
||||
20000008: 00 00 00 00 .*
|
||||
2000000c: 10 00 00 00 .*
|
||||
20000010: 00 00 00 00 .*
|
||||
20000014: 20 00 00 38 .*
|
||||
\.\.\.
|
||||
|
||||
0000000020000020 <f2>:
|
||||
20000020: 00 00 00 00 .*
|
||||
20000024: 10 00 00 04 .*
|
||||
20000028: 00 00 00 00 .*
|
||||
2000002c: 20 00 00 38 .*
|
||||
\.\.\.
|
||||
|
||||
0000000020000038 <TOC>:
|
||||
\.\.\.
|
2
ld/testsuite/ld-powerpc/aix-glink-1.ex
Normal file
2
ld/testsuite/ld-powerpc/aix-glink-1.ex
Normal file
@ -0,0 +1,2 @@
|
||||
f2
|
||||
foo
|
21
ld/testsuite/ld-powerpc/aix-glink-1.s
Normal file
21
ld/testsuite/ld-powerpc/aix-glink-1.s
Normal file
@ -0,0 +1,21 @@
|
||||
.toc
|
||||
.globl .f1
|
||||
.csect .f1[PR]
|
||||
.f1:
|
||||
blr
|
||||
|
||||
.globl .f2
|
||||
.csect .f2[PR]
|
||||
.f2:
|
||||
bl .f3
|
||||
|
||||
.globl .f3
|
||||
.csect .f3[PR]
|
||||
.f3:
|
||||
blr
|
||||
|
||||
.globl foo
|
||||
.csect foo[RW]
|
||||
foo:
|
||||
.long f1
|
||||
.long .ext
|
@ -91,6 +91,12 @@ set aix52tests {
|
||||
"" {aix-core-sec-3.s}
|
||||
{{objdump -h aix-core-sec-3.hd}}
|
||||
"aix-core-sec-3.so"}
|
||||
|
||||
{"Glink test 1"
|
||||
"-shared -bE:aix-glink-1.ex --unresolved-symbols=ignore-all"
|
||||
"" {aix-glink-1.s}
|
||||
{{objdump {-D -j.text -j.data} aix-glink-1-SIZE.dd}}
|
||||
"aix-glink-1.so"}
|
||||
}
|
||||
|
||||
foreach test $aix52tests {
|
||||
|
Loading…
x
Reference in New Issue
Block a user