diff options
author | Ian Lance Taylor <ian@airs.com> | 1996-04-18 22:55:54 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1996-04-18 22:55:54 +0000 |
commit | d6e0e2f786715baa7e5bd4b08cb371324ac31df2 (patch) | |
tree | 4a2bbbe9f1ecba5018a266c75dd227efe527b788 /bfd/cofflink.c | |
parent | 9590fa867b8d8132334654182ed606dd537fd741 (diff) | |
download | gdb-d6e0e2f786715baa7e5bd4b08cb371324ac31df2.zip gdb-d6e0e2f786715baa7e5bd4b08cb371324ac31df2.tar.gz gdb-d6e0e2f786715baa7e5bd4b08cb371324ac31df2.tar.bz2 |
* libcoff-in.h (struct coff_final_link_info): Add last_bf_index
and last_bf fields.
* libcoff.h: Rebuild.
* coffswap.h (coff_swap_aux_in): Swap endndx field for C_FCN
symbols.
(coff_swap_aux_out): Likewise.
* peicode.h (coff_swap_aux_in): Likewise.
(coff_swap_aux_out): Likewise.
* coffgen.c (coff_pointerize_aux): Check endndx field for C_FCN
symbols.
* cofflink.c (_bfd_coff_final_link): Initialize last_bf_index
field.
(_bfd_coff_link_input_bfd): Check endndx field for C_FCN symbols.
Fix up .bf endndx link fields.
* coff-ppc.c (ppc_bfd_coff_final_link): Initialize last_bf_index
field.
* xcofflink.c (xcoff_link_input_bfd): Check endndx field for C_FCN
symbols.
PR 9467.
Diffstat (limited to 'bfd/cofflink.c')
-rw-r--r-- | bfd/cofflink.c | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 4cc3d50..98753f0 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -447,6 +447,7 @@ _bfd_coff_final_link (abfd, info) finfo.strtab = NULL; finfo.section_info = NULL; finfo.last_file_index = -1; + finfo.last_bf_index = -1; finfo.internal_syms = NULL; finfo.sec_ptrs = NULL; finfo.sym_indices = NULL; @@ -1546,7 +1547,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) if (ISFCN (isymp->n_type) || ISTAG (isymp->n_sclass) - || isymp->n_sclass == C_BLOCK) + || isymp->n_sclass == C_BLOCK + || isymp->n_sclass == C_FCN) { indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l; if (indx > 0 @@ -1580,6 +1582,80 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) else auxp->x_sym.x_tagndx.l = symindx; } + + /* The .bf symbols are supposed to be linked through + the endndx field. We need to carry this list + across object files. */ + if (i == 0 + && h == NULL + && isymp->n_sclass == C_FCN + && (isymp->_n._n_n._n_zeroes != 0 + || isymp->_n._n_n._n_offset == 0) + && isymp->_n._n_name[0] == '.' + && isymp->_n._n_name[1] == 'b' + && isymp->_n._n_name[2] == 'f' + && isymp->_n._n_name[3] == '\0') + { + if (finfo->last_bf_index != -1) + { + finfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.l = + *indexp; + + if ((bfd_size_type) finfo->last_bf_index + >= syment_base) + { + PTR auxout; + + /* The last .bf symbol is in this input + file. This will only happen if the + assembler did not set up the .bf + endndx symbols correctly. */ + auxout = (PTR) (finfo->outsyms + + ((finfo->last_bf_index + - syment_base) + * osymesz)); + bfd_coff_swap_aux_out (output_bfd, + (PTR) &finfo->last_bf, + isymp->n_type, + isymp->n_sclass, + 0, isymp->n_numaux, + auxout); + } + else + { + /* We have already written out the last + .bf aux entry. We need to write it + out again. We borrow *outsym + temporarily. FIXME: This case should + be made faster. */ + bfd_coff_swap_aux_out (output_bfd, + (PTR) &finfo->last_bf, + isymp->n_type, + isymp->n_sclass, + 0, isymp->n_numaux, + (PTR) outsym); + if (bfd_seek (output_bfd, + (obj_sym_filepos (output_bfd) + + finfo->last_bf_index * osymesz), + SEEK_SET) != 0 + || bfd_write (outsym, osymesz, 1, + output_bfd) != osymesz) + return false; + } + } + + if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.l != 0) + finfo->last_bf_index = -1; + else + { + /* The endndx field of this aux entry must + be updated with the symbol number of the + next .bf symbol. */ + finfo->last_bf = *auxp; + finfo->last_bf_index = ((outsym - finfo->outsyms) + / osymesz); + } + } } if (h == NULL) |