From: Alan Modra Date: Wed, 1 Sep 2021 23:34:52 +0000 (+0930) Subject: PTR_ADD and NPTR_ADD for bfd.h X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=36f61bf2ad936edfb76eda706eb3b081a61d5a5a;p=binutils-gdb.git PTR_ADD and NPTR_ADD for bfd.h This defines a couple of macros used to avoid ubsan complaints about calculations involving NULL pointers. PTR_ADD should be used in the case where it is known that the offset is always zero with a NULL pointer, and you'd like to know if a non-zero offset is ever used. NPTR_ADD should be rarely used, but is defined for cases where a non-zero offset is expected and should be ignored if the pointer is NULL. bfd/ * bfd-in.h (PTR_ADD, NPTR_ADD): Define. * bfd-in2.h: Regenerate. * elf-eh-frame.c (adjust_eh_frame_local_symbols): Avoid NULL pointer calculations. * elflink.c (_bfd_elf_strip_zero_sized_dynamic_sections): Likewise. (bfd_elf_add_dt_needed_tag, elf_finalize_dynstr): Likewise. (elf_link_add_object_symbols, elf_link_input_bfd): Likewise. (bfd_elf_final_link, bfd_elf_gc_record_vtinherit): Likewise. binutils/ * objdump.c (disassemble_section): Use PTR_ADD for rel_ppend. --- diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index a4888f9f7f2..12176433045 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -113,6 +113,11 @@ typedef struct bfd bfd; # define TRUE 1 #endif +/* Silence "applying zero offset to null pointer" UBSAN warnings. */ +#define PTR_ADD(P,A) ((A) ? (P) + (A) : (P)) +/* Also prevent non-zero offsets from being applied to a null pointer. */ +#define NPTR_ADD(P,A) ((P) ? (P) + (A) : (P)) + #ifdef BFD64 #ifndef BFD_HOST_64_BIT diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 4156f747ad4..a0faeafc3dc 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -120,6 +120,11 @@ typedef struct bfd bfd; # define TRUE 1 #endif +/* Silence "applying zero offset to null pointer" UBSAN warnings. */ +#define PTR_ADD(P,A) ((A) ? (P) + (A) : (P)) +/* Also prevent non-zero offsets from being applied to a null pointer. */ +#define NPTR_ADD(P,A) ((P) ? (P) + (A) : (P)) + #ifdef BFD64 #ifndef BFD_HOST_64_BIT diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 6ce6d225cff..b5ec81436c5 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -1440,25 +1440,27 @@ static int adjust_eh_frame_local_symbols (const asection *sec, struct elf_reloc_cookie *cookie) { - unsigned int shndx; - Elf_Internal_Sym *sym; - Elf_Internal_Sym *end_sym; int adjusted = 0; - shndx = elf_section_data (sec)->this_idx; - end_sym = cookie->locsyms + cookie->locsymcount; - for (sym = cookie->locsyms + 1; sym < end_sym; ++sym) - if (sym->st_info <= ELF_ST_INFO (STB_LOCAL, STT_OBJECT) - && sym->st_shndx == shndx) - { - bfd_signed_vma delta = offset_adjust (sym->st_value, sec); + if (cookie->locsymcount > 1) + { + unsigned int shndx = elf_section_data (sec)->this_idx; + Elf_Internal_Sym *end_sym = cookie->locsyms + cookie->locsymcount; + Elf_Internal_Sym *sym; - if (delta != 0) + for (sym = cookie->locsyms + 1; sym < end_sym; ++sym) + if (sym->st_info <= ELF_ST_INFO (STB_LOCAL, STT_OBJECT) + && sym->st_shndx == shndx) { - adjusted = 1; - sym->st_value += delta; + bfd_signed_vma delta = offset_adjust (sym->st_value, sec); + + if (delta != 0) + { + adjusted = 1; + sym->st_value += delta; + } } - } + } return adjusted; } diff --git a/bfd/elflink.c b/bfd/elflink.c index 6fe90412b28..354cebbe766 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3649,7 +3649,7 @@ _bfd_elf_strip_zero_sized_dynamic_sections (struct bfd_link_info *info) else pp = &s->next; - if (strip_zero_sized_plt) + if (strip_zero_sized_plt && sdynamic->size != 0) for (extdyn = sdynamic->contents; extdyn < sdynamic->contents + sdynamic->size; extdyn = next) @@ -3709,7 +3709,7 @@ bfd_elf_add_dt_needed_tag (bfd *abfd, struct bfd_link_info *info) bed = get_elf_backend_data (hash_table->dynobj); sdyn = bfd_get_linker_section (hash_table->dynobj, ".dynamic"); - if (sdyn != NULL) + if (sdyn != NULL && sdyn->size != 0) for (extdyn = sdyn->contents; extdyn < sdyn->contents + sdyn->size; extdyn += bed->s->sizeof_dyn) @@ -3858,7 +3858,7 @@ elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info) /* Update all .dynamic entries referencing .dynstr strings. */ for (extdyn = sdyn->contents; - extdyn < sdyn->contents + sdyn->size; + extdyn < PTR_ADD (sdyn->contents, sdyn->size); extdyn += bed->s->sizeof_dyn) { Elf_Internal_Dyn dyn; @@ -4276,7 +4276,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) | DYN_NO_NEEDED)) == 0; s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) + if (s != NULL && s->size != 0) { bfd_byte *dynbuf; bfd_byte *extdyn; @@ -4650,7 +4650,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) (_("%pB: plugin needed to handle lto object"), abfd); } - for (isym = isymbuf, isymend = isymbuf + extsymcount; + for (isym = isymbuf, isymend = PTR_ADD (isymbuf, extsymcount); isym < isymend; isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL)) { @@ -10913,7 +10913,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) /* Find local symbol sections and adjust values of symbols in SEC_MERGE sections. Write out those local symbols we know are going into the output file. */ - isymend = isymbuf + locsymcount; + isymend = PTR_ADD (isymbuf, locsymcount); for (isym = isymbuf, pindex = flinfo->indices, ppsection = flinfo->sections; isym < isymend; isym++, pindex++, ppsection++) @@ -11457,7 +11457,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) irela = internal_relocs; irelaend = irela + o->reloc_count; - rel_hash = esdo->rel.hashes + esdo->rel.count; + rel_hash = PTR_ADD (esdo->rel.hashes, esdo->rel.count); /* We start processing the REL relocs, if any. When we reach IRELAMID in the loop, we switch to the RELA relocs. */ irelamid = irela; @@ -11483,7 +11483,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) if (irela == irelamid) { - rel_hash = esdo->rela.hashes + esdo->rela.count; + rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count); rela_hash_list = rel_hash; rela_normal = bed->rela_normal; } @@ -12957,7 +12957,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) BFD_ASSERT (o != NULL); dyncon = o->contents; - dynconend = o->contents + o->size; + dynconend = PTR_ADD (o->contents, o->size); for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) { Elf_Internal_Dyn dyn; @@ -13160,7 +13160,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* Check for DT_TEXTREL (late, in case the backend removes it). */ if (bfd_link_textrel_check (info) - && (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL) + && (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL + && o->size != 0) { bfd_byte *dyncon, *dynconend; @@ -14206,7 +14207,7 @@ bfd_elf_gc_record_vtinherit (bfd *abfd, extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info; sym_hashes = elf_sym_hashes (abfd); - sym_hashes_end = sym_hashes + extsymcount; + sym_hashes_end = PTR_ADD (sym_hashes, extsymcount); /* Hunt down the child symbol, which is in this section at the same offset as the relocation. */ diff --git a/binutils/objdump.c b/binutils/objdump.c index f78b70a8d40..27bfb420399 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -3208,7 +3208,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) } } } - rel_ppend = rel_pp + rel_count; + rel_ppend = PTR_ADD (rel_pp, rel_count); if (!bfd_malloc_and_get_section (abfd, section, &data)) {