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:
Richard Sandiford 2009-03-14 09:17:32 +00:00
parent 9f0eb2327b
commit 858ef0ce3b
16 changed files with 463 additions and 231 deletions

View file

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

View file

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

View file

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

View file

@ -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"),

View file

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

View file

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

View file

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

View file

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

View file

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

View 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'

View 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>:
\.\.\.

View 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'

View 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>:
\.\.\.

View file

@ -0,0 +1,2 @@
f2
foo

View 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

View file

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