Avoid ubsan bug complaining about &p->field
I reckon it's quite OK to write &p->field in C when p might be NULL, and lots of old C programmers probably agree with me. However, ubsan disagrees and so do some people I respect. I suspect C++ influence is to blame for the ubsan behaviour. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92634. So far no one has educated me as to why I'm wrong to claim that there isn't anything in the C standard to say that p->field is always (*p).field. Note 79 doesn't quite do that because it doesn't cover null pointers. If there was such an equivalence then you could claim &p->field has a null pointer reference when p is NULL, even though no C compiler would ever dereference p. Anyway, to silence ubsan I'm going to apply the following though I prefer to avoid casts when possible. And I'm using (void *) deliberately because this is C, not C++! * ldlang.c (lang_output_section_find_by_flags): Don't use &p->field when p might be NULL. * ldelf.c (output_rel_find, ldelf_place_orphan): Likewise. (insert_os_after, lang_insert_orphan, lookup_name): Likewise. (strip_excluded_output_sections, lang_clear_os_map): Likewise. (lang_check, lang_for_each_input_file): Likewise. (lang_reset_memory_regions, find_replacements_insert_point): Likewise. (find_rescan_insertion, lang_propagate_lma_regions): Likewise. (lang_record_phdrs): Likewise. * emultempl/alphaelf.em (alpha_after_open): Likewise. * emultempl/mmo.em (mmo_place_orphan): Likewise. * emultempl/pe.em (gld_${EMULATION_NAME}_place_orphan): Likewise. * emultempl/pep.em (gld_${EMULATION_NAME}_place_orphan): Likewise. * emultempl/ppc32elf.em (ppc_after_check_relocs): Likewise. * emultempl/spuelf.em (spu_before_allocation): Likewise. (embedded_spu_file): Likewise.
This commit is contained in:
parent
100b122fc1
commit
8ce18f9cdf
19
ld/ChangeLog
19
ld/ChangeLog
@ -1,3 +1,22 @@
|
|||||||
|
2019-12-26 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* ldlang.c (lang_output_section_find_by_flags): Don't use &p->field
|
||||||
|
when p might be NULL.
|
||||||
|
* ldelf.c (output_rel_find, ldelf_place_orphan): Likewise.
|
||||||
|
(insert_os_after, lang_insert_orphan, lookup_name): Likewise.
|
||||||
|
(strip_excluded_output_sections, lang_clear_os_map): Likewise.
|
||||||
|
(lang_check, lang_for_each_input_file): Likewise.
|
||||||
|
(lang_reset_memory_regions, find_replacements_insert_point): Likewise.
|
||||||
|
(find_rescan_insertion, lang_propagate_lma_regions): Likewise.
|
||||||
|
(lang_record_phdrs): Likewise.
|
||||||
|
* emultempl/alphaelf.em (alpha_after_open): Likewise.
|
||||||
|
* emultempl/mmo.em (mmo_place_orphan): Likewise.
|
||||||
|
* emultempl/pe.em (gld_${EMULATION_NAME}_place_orphan): Likewise.
|
||||||
|
* emultempl/pep.em (gld_${EMULATION_NAME}_place_orphan): Likewise.
|
||||||
|
* emultempl/ppc32elf.em (ppc_after_check_relocs): Likewise.
|
||||||
|
* emultempl/spuelf.em (spu_before_allocation): Likewise.
|
||||||
|
(embedded_spu_file): Likewise.
|
||||||
|
|
||||||
2019-12-19 Alan Modra <amodra@gmail.com>
|
2019-12-19 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* testsuite/lib/ld-lib.exp (uses_genelf): Remove moxie.
|
* testsuite/lib/ld-lib.exp (uses_genelf): Remove moxie.
|
||||||
|
@ -47,7 +47,7 @@ alpha_after_open (void)
|
|||||||
lang_output_section_statement_type *plt_os[2];
|
lang_output_section_statement_type *plt_os[2];
|
||||||
|
|
||||||
num_plt = 0;
|
num_plt = 0;
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
|
@ -163,7 +163,7 @@ mmo_place_orphan (asection *s,
|
|||||||
|
|
||||||
/* We have to find the oss before this one, so we can use that as
|
/* We have to find the oss before this one, so we can use that as
|
||||||
"after". */
|
"after". */
|
||||||
for (lookup = &lang_os_list.head->output_section_statement;
|
for (lookup = (void *) lang_os_list.head;
|
||||||
lookup != NULL && lookup->next != before;
|
lookup != NULL && lookup->next != before;
|
||||||
lookup = lookup->next)
|
lookup = lookup->next)
|
||||||
;
|
;
|
||||||
|
@ -2151,7 +2151,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
|
|||||||
NULL);
|
NULL);
|
||||||
if (after == NULL)
|
if (after == NULL)
|
||||||
/* *ABS* is always the first output section statement. */
|
/* *ABS* is always the first output section statement. */
|
||||||
after = &lang_os_list.head->output_section_statement;
|
after = (void *) lang_os_list.head;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All sections in an executable must be aligned to a page boundary.
|
/* All sections in an executable must be aligned to a page boundary.
|
||||||
|
@ -1950,7 +1950,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
|
|||||||
NULL);
|
NULL);
|
||||||
if (after == NULL)
|
if (after == NULL)
|
||||||
/* *ABS* is always the first output section statement. */
|
/* *ABS* is always the first output section statement. */
|
||||||
after = &lang_os_list.head->output_section_statement;
|
after = (void *) lang_os_list.head;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All sections in an executable must be aligned to a page boundary.
|
/* All sections in an executable must be aligned to a page boundary.
|
||||||
|
@ -79,7 +79,7 @@ ppc_after_check_relocs (void)
|
|||||||
|
|
||||||
num_got = 0;
|
num_got = 0;
|
||||||
num_plt = 0;
|
num_plt = 0;
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
|
@ -290,7 +290,7 @@ spu_before_allocation (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure alignment of overlay sections is sufficient. */
|
/* Ensure alignment of overlay sections is sufficient. */
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
if (os->bfd_section != NULL
|
if (os->bfd_section != NULL
|
||||||
@ -512,7 +512,7 @@ embedded_spu_file (lang_input_statement_type *entry, const char *flags)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
for (search = &input_file_chain.head->input_statement;
|
for (search = (void *) input_file_chain.head;
|
||||||
search != NULL;
|
search != NULL;
|
||||||
search = search->next_real_file)
|
search = search->next_real_file)
|
||||||
if (search->filename != NULL)
|
if (search->filename != NULL)
|
||||||
|
@ -1780,7 +1780,7 @@ output_rel_find (int isdyn, int rela)
|
|||||||
lang_output_section_statement_type *last_rel = NULL;
|
lang_output_section_statement_type *last_rel = NULL;
|
||||||
lang_output_section_statement_type *last_rel_alloc = NULL;
|
lang_output_section_statement_type *last_rel_alloc = NULL;
|
||||||
|
|
||||||
for (lookup = &lang_os_list.head->output_section_statement;
|
for (lookup = (void *) lang_os_list.head;
|
||||||
lookup != NULL;
|
lookup != NULL;
|
||||||
lookup = lookup->next)
|
lookup = lookup->next)
|
||||||
{
|
{
|
||||||
@ -1952,7 +1952,7 @@ ldelf_place_orphan (asection *s, const char *secname, int constraint)
|
|||||||
{
|
{
|
||||||
/* Find the output mbind section with the same type, attributes
|
/* Find the output mbind section with the same type, attributes
|
||||||
and sh_info field. */
|
and sh_info field. */
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
if (os->bfd_section != NULL
|
if (os->bfd_section != NULL
|
||||||
@ -2129,7 +2129,7 @@ ldelf_place_orphan (asection *s, const char *secname, int constraint)
|
|||||||
_bfd_elf_match_sections_by_type);
|
_bfd_elf_match_sections_by_type);
|
||||||
if (after == NULL)
|
if (after == NULL)
|
||||||
/* *ABS* is always the first output section statement. */
|
/* *ABS* is always the first output section statement. */
|
||||||
after = &lang_os_list.head->output_section_statement;
|
after = (void *) lang_os_list.head;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
|
return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
|
||||||
|
30
ld/ldlang.c
30
ld/ldlang.c
@ -1552,7 +1552,7 @@ lang_output_section_find_by_flags (const asection *sec,
|
|||||||
|
|
||||||
/* We know the first statement on this list is *ABS*. May as well
|
/* We know the first statement on this list is *ABS*. May as well
|
||||||
skip it. */
|
skip it. */
|
||||||
first = &lang_os_list.head->output_section_statement;
|
first = (void *) lang_os_list.head;
|
||||||
first = first->next;
|
first = first->next;
|
||||||
|
|
||||||
/* First try for an exact match. */
|
/* First try for an exact match. */
|
||||||
@ -1780,7 +1780,7 @@ insert_os_after (lang_output_section_statement_type *after)
|
|||||||
lang_statement_union_type **assign = NULL;
|
lang_statement_union_type **assign = NULL;
|
||||||
bfd_boolean ignore_first;
|
bfd_boolean ignore_first;
|
||||||
|
|
||||||
ignore_first = after == &lang_os_list.head->output_section_statement;
|
ignore_first = after == (void *) lang_os_list.head;
|
||||||
|
|
||||||
for (where = &after->header.next;
|
for (where = &after->header.next;
|
||||||
*where != NULL;
|
*where != NULL;
|
||||||
@ -1904,7 +1904,7 @@ lang_insert_orphan (asection *s,
|
|||||||
/* Shuffle the bfd section list to make the output file look
|
/* Shuffle the bfd section list to make the output file look
|
||||||
neater. This is really only cosmetic. */
|
neater. This is really only cosmetic. */
|
||||||
if (place->section == NULL
|
if (place->section == NULL
|
||||||
&& after != &lang_os_list.head->output_section_statement)
|
&& after != (void *) lang_os_list.head)
|
||||||
{
|
{
|
||||||
asection *bfd_section = after->bfd_section;
|
asection *bfd_section = after->bfd_section;
|
||||||
|
|
||||||
@ -2846,7 +2846,7 @@ lookup_name (const char *name)
|
|||||||
{
|
{
|
||||||
lang_input_statement_type *search;
|
lang_input_statement_type *search;
|
||||||
|
|
||||||
for (search = &input_file_chain.head->input_statement;
|
for (search = (void *) input_file_chain.head;
|
||||||
search != NULL;
|
search != NULL;
|
||||||
search = search->next_real_file)
|
search = search->next_real_file)
|
||||||
{
|
{
|
||||||
@ -4329,7 +4329,7 @@ strip_excluded_output_sections (void)
|
|||||||
lang_reset_memory_regions ();
|
lang_reset_memory_regions ();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
@ -4390,7 +4390,7 @@ lang_clear_os_map (void)
|
|||||||
if (map_head_is_link_order)
|
if (map_head_is_link_order)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
@ -6728,7 +6728,7 @@ lang_check (void)
|
|||||||
bfd *input_bfd;
|
bfd *input_bfd;
|
||||||
const bfd_arch_info_type *compatible;
|
const bfd_arch_info_type *compatible;
|
||||||
|
|
||||||
for (file = &file_chain.head->input_statement;
|
for (file = (void *) file_chain.head;
|
||||||
file != NULL;
|
file != NULL;
|
||||||
file = file->next)
|
file = file->next)
|
||||||
{
|
{
|
||||||
@ -7070,7 +7070,7 @@ lang_for_each_input_file (void (*func) (lang_input_statement_type *))
|
|||||||
{
|
{
|
||||||
lang_input_statement_type *f;
|
lang_input_statement_type *f;
|
||||||
|
|
||||||
for (f = &input_file_chain.head->input_statement;
|
for (f = (void *) input_file_chain.head;
|
||||||
f != NULL;
|
f != NULL;
|
||||||
f = f->next_real_file)
|
f = f->next_real_file)
|
||||||
if (f->flags.real)
|
if (f->flags.real)
|
||||||
@ -7196,7 +7196,7 @@ lang_reset_memory_regions (void)
|
|||||||
p->last_os = NULL;
|
p->last_os = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
@ -7433,8 +7433,8 @@ static lang_input_statement_type *
|
|||||||
find_replacements_insert_point (bfd_boolean *before)
|
find_replacements_insert_point (bfd_boolean *before)
|
||||||
{
|
{
|
||||||
lang_input_statement_type *claim1, *lastobject;
|
lang_input_statement_type *claim1, *lastobject;
|
||||||
lastobject = &input_file_chain.head->input_statement;
|
lastobject = (void *) input_file_chain.head;
|
||||||
for (claim1 = &file_chain.head->input_statement;
|
for (claim1 = (void *) file_chain.head;
|
||||||
claim1 != NULL;
|
claim1 != NULL;
|
||||||
claim1 = claim1->next)
|
claim1 = claim1->next)
|
||||||
{
|
{
|
||||||
@ -7476,7 +7476,7 @@ find_rescan_insertion (lang_input_statement_type *add)
|
|||||||
file chain if it is full of archive elements. Archives don't
|
file chain if it is full of archive elements. Archives don't
|
||||||
appear on the file chain, but if an element has been extracted
|
appear on the file chain, but if an element has been extracted
|
||||||
then their input_statement->next points at it. */
|
then their input_statement->next points at it. */
|
||||||
for (f = &input_file_chain.head->input_statement;
|
for (f = (void *) input_file_chain.head;
|
||||||
f != NULL;
|
f != NULL;
|
||||||
f = f->next_real_file)
|
f = f->next_real_file)
|
||||||
{
|
{
|
||||||
@ -7609,7 +7609,7 @@ lang_propagate_lma_regions (void)
|
|||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
|
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
@ -8286,7 +8286,7 @@ lang_record_phdrs (void)
|
|||||||
bfd_vma at;
|
bfd_vma at;
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
@ -8372,7 +8372,7 @@ lang_record_phdrs (void)
|
|||||||
free (secs);
|
free (secs);
|
||||||
|
|
||||||
/* Make sure all the phdr assignments succeeded. */
|
/* Make sure all the phdr assignments succeeded. */
|
||||||
for (os = &lang_os_list.head->output_section_statement;
|
for (os = (void *) lang_os_list.head;
|
||||||
os != NULL;
|
os != NULL;
|
||||||
os = os->next)
|
os = os->next)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user