X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fvms-alpha.c;h=e31a9e4ca10bca344dab67ea208b0784ffb85458;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=594363b32afe7ad590515f9610851e5bf68a0402;hpb=f75fbe8ad2e3d9b34bf1f448a6df328ff361822f;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index 594363b32a..e31a9e4ca1 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -1611,26 +1611,35 @@ dst_retrieve_location (bfd *abfd, bfd_vma *loc) static bfd_boolean image_write (bfd *abfd, unsigned char *ptr, unsigned int size) { + asection *sec = PRIV (image_section); + size_t off = PRIV (image_offset); + + /* Check bounds. */ + if (off > sec->size + || size > sec->size - off) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + #if VMS_DEBUG _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size, - (long)PRIV (image_offset)); + (long) off)); #endif if (PRIV (image_section)->contents != NULL) + memcpy (sec->contents + off, ptr, size); + else { - asection *sec = PRIV (image_section); - size_t off = PRIV (image_offset); - - /* Check bounds. */ - if (off > sec->size - || size > sec->size - off) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - memcpy (sec->contents + off, ptr, size); + unsigned int i; + for (i = 0; i < size; i++) + if (ptr[i] != 0) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } } + #if VMS_DEBUG _bfd_hexdump (9, ptr, size, 0); #endif @@ -1916,11 +1925,12 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) return FALSE; } ptr += 4; + cmd_length -= 4; #if VMS_DEBUG _bfd_vms_debug (4, "etir: %s(%d)\n", _bfd_vms_etir_name (cmd), cmd); - _bfd_hexdump (8, ptr, cmd_length - 4, 0); + _bfd_hexdump (8, ptr, cmd_length, 0); #endif switch (cmd) @@ -1930,7 +1940,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) stack 32 bit value of symbol (high bits set to 0). */ case ETIR__C_STA_GBL: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); if (!_bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h))) return FALSE; break; @@ -1940,7 +1950,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) stack 32 bit value, sign extend to 64 bit. */ case ETIR__C_STA_LW: - if (ptr + 4 > maxptr) + if (cmd_length < 4) goto corrupt_etir; if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE)) return FALSE; @@ -1951,7 +1961,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) stack 64 bit value of symbol. */ case ETIR__C_STA_QW: - if (ptr + 8 > maxptr) + if (cmd_length < 8) goto corrupt_etir; if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE)) return FALSE; @@ -1967,7 +1977,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { int psect; - if (ptr + 12 > maxptr) + if (cmd_length < 12) goto corrupt_etir; psect = bfd_getl32 (ptr); if ((unsigned int) psect >= PRIV (section_count)) @@ -1998,7 +2008,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) return FALSE; if (rel1 != RELC_NONE) goto bad_context; - image_write_b (abfd, (unsigned int) op1 & 0xff); + if (!image_write_b (abfd, (unsigned int) op1 & 0xff)) + return FALSE; break; /* Store word: pop stack, write word @@ -2008,7 +2019,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) return FALSE; if (rel1 != RELC_NONE) goto bad_context; - image_write_w (abfd, (unsigned int) op1 & 0xffff); + if (!image_write_w (abfd, (unsigned int) op1 & 0xffff)) + return FALSE; break; /* Store longword: pop stack, write longword @@ -2034,7 +2046,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) if (!alpha_vms_add_lw_reloc (info)) return FALSE; } - image_write_l (abfd, op1); + if (!image_write_l (abfd, op1)) + return FALSE; break; /* Store quadword: pop stack, write quadword @@ -2056,7 +2069,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) if (!alpha_vms_add_qw_reloc (info)) return FALSE; } - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return FALSE; break; /* Store immediate repeated: pop stack for repeat count @@ -2066,22 +2080,28 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { int size; - if (ptr + 4 > maxptr) + if (cmd_length < 4) goto corrupt_etir; size = bfd_getl32 (ptr); + if (size > cmd_length - 4) + goto corrupt_etir; if (!_bfd_vms_pop (abfd, &op1, &rel1)) return FALSE; if (rel1 != RELC_NONE) goto bad_context; + if (size == 0) + break; + op1 &= 0xffffffff; while (op1-- > 0) - image_write (abfd, ptr + 4, size); + if (!image_write (abfd, ptr + 4, size)) + return FALSE; } break; /* Store global: write symbol value arg: cs global symbol name. */ case ETIR__C_STO_GBL: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); if (h && h->sym) { if (h->sym->typ == EGSD__C_SYMG) @@ -2099,13 +2119,14 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) return FALSE; } } - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return FALSE; break; /* Store code address: write address of entry point arg: cs global symbol name (procedure). */ case ETIR__C_STO_CA: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); if (h && h->sym) { if (h->sym->flags & EGSY__V_NORM) @@ -2131,7 +2152,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) abort (); } } - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return FALSE; break; /* Store offset to psect: pop stack, add low 32 bits to base of psect @@ -2145,7 +2167,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1); rel1 = RELC_REL; - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return FALSE; break; /* Store immediate @@ -2155,10 +2178,11 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { unsigned int size; - if (ptr + 4 > maxptr) + if (cmd_length < 4) goto corrupt_etir; size = bfd_getl32 (ptr); - image_write (abfd, ptr + 4, size); + if (!image_write (abfd, ptr + 4, size)) + return FALSE; } break; @@ -2169,11 +2193,12 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) store global longword: store 32bit value of symbol arg: cs symbol name. */ case ETIR__C_STO_GBL_LW: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); #if 0 abort (); #endif - image_write_l (abfd, op1); + if (!image_write_l (abfd, op1)) + return FALSE; break; case ETIR__C_STO_RB: @@ -2222,7 +2247,9 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) da signature. */ case ETIR__C_STC_LP_PSB: - _bfd_vms_get_value (abfd, ptr + 4, maxptr, info, &op1, &h); + if (cmd_length < 4) + goto corrupt_etir; + _bfd_vms_get_value (abfd, ptr + 4, ptr + cmd_length, info, &op1, &h); if (h && h->sym) { if (h->sym->typ == EGSD__C_SYMG) @@ -2246,8 +2273,9 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) op1 = 0; op2 = 0; } - image_write_q (abfd, op1); - image_write_q (abfd, op2); + if (!image_write_q (abfd, op1) + || !image_write_q (abfd, op2)) + return FALSE; break; /* 205 Store-conditional NOP at address of global @@ -2320,7 +2348,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) /* Augment relocation base: increment image location counter by offset arg: lw offset value. */ case ETIR__C_CTL_AUGRB: - if (ptr + 4 > maxptr) + if (cmd_length < 4) goto corrupt_etir; op1 = bfd_getl32 (ptr); image_inc_ptr (abfd, op1); @@ -2418,8 +2446,11 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) return FALSE; if (rel1 != RELC_NONE || rel2 != RELC_NONE) goto bad_context; - if (op2 == 0) + if (op1 == 0) { + /* Divide by zero is supposed to give a result of zero, + and a non-fatal warning message. */ + _bfd_error_handler (_("%s divide by zero"), "ETIR__C_OPR_DIV"); if (!_bfd_vms_push (abfd, 0, RELC_NONE)) return FALSE; } @@ -2531,7 +2562,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) break; } - ptr += cmd_length - 4; + ptr += cmd_length; } return TRUE;