+2020-05-22 Alan Modra <amodra@gmail.com>
+
+ PR 25882
+ * elf32-ppc.c (_bfd_elf_ppc_merge_fp_attributes): Don't init FP
+ attributes from shared libraries, and do not return an error if
+ they don't match.
+
2020-05-21 Alan Modra <amodra@gmail.com>
PR 25993
obj_attribute *in_attr, *in_attrs;
obj_attribute *out_attr, *out_attrs;
bfd_boolean ret = TRUE;
+ bfd_boolean warn_only;
+
+ /* We only warn about shared library mismatches, because common
+ libraries advertise support for a particular long double variant
+ but actually support more than one variant. For example, glibc
+ typically supports 128-bit IBM long double in the shared library
+ but has a compatibility static archive for 64-bit long double.
+ The linker doesn't have the smarts to see that an app using
+ object files marked as 64-bit long double call the compatibility
+ layer objects and only from there call into the shared library. */
+ warn_only = (ibfd->flags & DYNAMIC) != 0;
in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
;
else if (out_fp == 0)
{
- out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
- out_attr->i ^= in_fp;
- last_fp = ibfd;
+ if (!warn_only)
+ {
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
+ out_attr->i ^= in_fp;
+ last_fp = ibfd;
+ }
}
else if (out_fp != 2 && in_fp == 2)
{
/* xgettext:c-format */
(_("%pB uses hard float, %pB uses soft float"),
last_fp, ibfd);
- ret = FALSE;
+ ret = warn_only;
}
else if (out_fp == 2 && in_fp != 2)
{
/* xgettext:c-format */
(_("%pB uses hard float, %pB uses soft float"),
ibfd, last_fp);
- ret = FALSE;
+ ret = warn_only;
}
else if (out_fp == 1 && in_fp == 3)
{
/* xgettext:c-format */
(_("%pB uses double-precision hard float, "
"%pB uses single-precision hard float"), last_fp, ibfd);
- ret = FALSE;
+ ret = warn_only;
}
else if (out_fp == 3 && in_fp == 1)
{
/* xgettext:c-format */
(_("%pB uses double-precision hard float, "
"%pB uses single-precision hard float"), ibfd, last_fp);
- ret = FALSE;
+ ret = warn_only;
}
in_fp = in_attr->i & 0xc;
;
else if (out_fp == 0)
{
- out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
- out_attr->i ^= in_fp;
- last_ld = ibfd;
+ if (!warn_only)
+ {
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
+ out_attr->i ^= in_fp;
+ last_ld = ibfd;
+ }
}
else if (out_fp != 2 * 4 && in_fp == 2 * 4)
{
/* xgettext:c-format */
(_("%pB uses 64-bit long double, "
"%pB uses 128-bit long double"), ibfd, last_ld);
- ret = FALSE;
+ ret = warn_only;
}
else if (in_fp != 2 * 4 && out_fp == 2 * 4)
{
/* xgettext:c-format */
(_("%pB uses 64-bit long double, "
"%pB uses 128-bit long double"), last_ld, ibfd);
- ret = FALSE;
+ ret = warn_only;
}
else if (out_fp == 1 * 4 && in_fp == 3 * 4)
{
/* xgettext:c-format */
(_("%pB uses IBM long double, "
"%pB uses IEEE long double"), last_ld, ibfd);
- ret = FALSE;
+ ret = warn_only;
}
else if (out_fp == 3 * 4 && in_fp == 1 * 4)
{
/* xgettext:c-format */
(_("%pB uses IBM long double, "
"%pB uses IEEE long double"), ibfd, last_ld);
- ret = FALSE;
+ ret = warn_only;
}
}
+2020-05-22 Alan Modra <amodra@gmail.com>
+
+ PR 25882
+ * powerpc.cc (merge_object_attributes): Replace name param with
+ obj param. Update callers. Don't init FP attributes from shared
+ libraries, and do not emit an error if they don't match.
+
2020-05-15 Nikita Ermakov <coffe92@gmail.com>
* powerpc.cc (do_gc_mark_symbol): Don't segfault on plugin symbols.
// Merge object attributes from input object with those in the output.
void
- merge_object_attributes(const char*, const Attributes_section_data*);
+ merge_object_attributes(const Object*, const Attributes_section_data*);
private:
Powerpc_relobj<size, big_endian>* ppc_relobj
= static_cast<Powerpc_relobj<size, big_endian>*>(*p);
if (ppc_relobj->attributes_section_data())
- this->merge_object_attributes(ppc_relobj->name().c_str(),
+ this->merge_object_attributes(ppc_relobj,
ppc_relobj->attributes_section_data());
}
for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
Powerpc_dynobj<size, big_endian>* ppc_dynobj
= static_cast<Powerpc_dynobj<size, big_endian>*>(*p);
if (ppc_dynobj->attributes_section_data())
- this->merge_object_attributes(ppc_dynobj->name().c_str(),
+ this->merge_object_attributes(ppc_dynobj,
ppc_dynobj->attributes_section_data());
}
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::merge_object_attributes(
- const char* name,
+ const Object* obj,
const Attributes_section_data* pasd)
{
// Return if there is no attributes section data.
Object_attribute* out_attr
= this->attributes_section_data_->known_attributes(vendor);
+ const char* name = obj->name().c_str();
const char* err;
const char* first;
const char* second;
int tag = elfcpp::Tag_GNU_Power_ABI_FP;
int in_fp = in_attr[tag].int_value() & 0xf;
int out_fp = out_attr[tag].int_value() & 0xf;
+ bool warn_only = obj->is_dynamic();
if (in_fp != out_fp)
{
err = NULL;
;
else if ((out_fp & 3) == 0)
{
- out_fp |= in_fp & 3;
- out_attr[tag].set_int_value(out_fp);
- out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
- this->last_fp_ = name;
+ if (!warn_only)
+ {
+ out_fp |= in_fp & 3;
+ out_attr[tag].set_int_value(out_fp);
+ out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
+ this->last_fp_ = name;
+ }
}
else if ((out_fp & 3) != 2 && (in_fp & 3) == 2)
{
;
else if ((out_fp & 0xc) == 0)
{
- out_fp |= in_fp & 0xc;
- out_attr[tag].set_int_value(out_fp);
- out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
- this->last_ld_ = name;
+ if (!warn_only)
+ {
+ out_fp |= in_fp & 0xc;
+ out_attr[tag].set_int_value(out_fp);
+ out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
+ this->last_ld_ = name;
+ }
}
else if ((out_fp & 0xc) != 2 * 4 && (in_fp & 0xc) == 2 * 4)
{
if (err)
{
if (parameters->options().warn_mismatch())
- gold_error(_(err), first, second);
+ {
+ if (warn_only)
+ gold_warning(_(err), first, second);
+ else
+ gold_error(_(err), first, second);
+ }
// Arrange for this attribute to be deleted. It's better to
// say "don't know" about a file than to wrongly claim compliance.
- out_attr[tag].set_type(0);
+ if (!warn_only)
+ out_attr[tag].set_type(0);
}
}