| 3765 | through the whole unit looking for function tags. */ |
| 3766 | |
| 3767 | static void |
| 3768 | read_function_info (struct backtrace_state *state, struct dwarf_data *ddata, |
| 3769 | const struct line_header *lhdr, |
| 3770 | backtrace_error_callback error_callback, void *data, |
| 3771 | struct unit *u, struct function_vector *fvec, |
| 3772 | struct function_addrs **ret_addrs, |
| 3773 | size_t *ret_addrs_count) |
| 3774 | { |
| 3775 | struct function_vector lvec; |
| 3776 | struct function_vector *pfvec; |
| 3777 | struct dwarf_buf unit_buf; |
| 3778 | struct function_addrs *addrs; |
| 3779 | size_t addrs_count; |
| 3780 | |
| 3781 | /* Use FVEC if it is not NULL. Otherwise use our own vector. */ |
| 3782 | if (fvec != NULL) |
| 3783 | pfvec = fvec; |
| 3784 | else |
| 3785 | { |
| 3786 | memset (&lvec, 0, sizeof lvec); |
| 3787 | pfvec = &lvec; |
| 3788 | } |
| 3789 | |
| 3790 | unit_buf.name = ".debug_info"; |
| 3791 | unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO]; |
| 3792 | unit_buf.buf = u->unit_data; |
| 3793 | unit_buf.left = u->unit_data_len; |
| 3794 | unit_buf.is_bigendian = ddata->is_bigendian; |
| 3795 | unit_buf.error_callback = error_callback; |
| 3796 | unit_buf.data = data; |
| 3797 | unit_buf.reported_underflow = 0; |
| 3798 | |
| 3799 | while (unit_buf.left > 0) |
| 3800 | { |
| 3801 | if (!read_function_entry (state, ddata, u, 0, &unit_buf, lhdr, |
| 3802 | error_callback, data, pfvec, pfvec)) |
| 3803 | return; |
| 3804 | } |
| 3805 | |
| 3806 | if (pfvec->count == 0) |
| 3807 | return; |
| 3808 | |
| 3809 | addrs_count = pfvec->count; |
| 3810 | |
| 3811 | if (fvec == NULL) |
| 3812 | { |
| 3813 | if (!backtrace_vector_release (state, &lvec.vec, error_callback, data)) |
| 3814 | return; |
| 3815 | addrs = (struct function_addrs *) pfvec->vec.base; |
| 3816 | } |
| 3817 | else |
| 3818 | { |
| 3819 | /* Finish this list of addresses, but leave the remaining space in |
| 3820 | the vector available for the next function unit. */ |
| 3821 | addrs = ((struct function_addrs *) |
| 3822 | backtrace_vector_finish (state, &fvec->vec, |
| 3823 | error_callback, data)); |
| 3824 | if (addrs == NULL) |
no test coverage detected