diff options
-rw-r--r-- | bfd/ChangeLog | 21 | ||||
-rw-r--r-- | bfd/coff-ppc.c | 1 | ||||
-rw-r--r-- | bfd/coffgen.c | 2 | ||||
-rw-r--r-- | bfd/cofflink.c | 78 | ||||
-rw-r--r-- | bfd/libcoff-in.h | 10 | ||||
-rw-r--r-- | bfd/libcoff.h | 10 | ||||
-rw-r--r-- | bfd/peicode.h | 4 |
7 files changed, 120 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4fcf3f0..a4db9d6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,24 @@ +Thu Apr 18 18:51:18 1996 Ian Lance Taylor <ian@cygnus.com> + + * 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. + Wed Apr 17 12:08:24 1996 Michael Meissner <meissner@tiktok.cygnus.com> * pe{,i}-ppc.c (PPC_PE): Define instead of PPC, so that compiling diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c index d49348f..cad654a 100644 --- a/bfd/coff-ppc.c +++ b/bfd/coff-ppc.c @@ -2713,6 +2713,7 @@ ppc_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; diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 9340fed..76e9430 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1355,7 +1355,7 @@ coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent) /* Otherwise patch up */ #define N_TMASK coff_data (abfd)->local_n_tmask #define N_BTSHFT coff_data (abfd)->local_n_btshft - if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK) + if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN) && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) { auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = 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) diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index ad0b983..e2242f5 100644 --- a/bfd/libcoff-in.h +++ b/bfd/libcoff-in.h @@ -1,7 +1,10 @@ /* BFD COFF object file private structure. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. + Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. Written by Cygnus Support. +** NOTE: libcoff.h is a GENERATED file. Don't change it; instead, +** change libcoff-in.h or coffcode.h. + This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify @@ -405,6 +408,11 @@ struct coff_final_link_info long last_file_index; /* Contents of last C_FILE symbol. */ struct internal_syment last_file; + /* Symbol index of first aux entry of last .bf symbol with an empty + endndx field (-1 if none). */ + long last_bf_index; + /* Contents of last_bf_index aux entry. */ + union internal_auxent last_bf; /* Hash table used to merge debug information. */ struct coff_debug_merge_hash_table debug_merge; /* Buffer large enough to hold swapped symbols of any input file. */ diff --git a/bfd/libcoff.h b/bfd/libcoff.h index 41888e2..2614310 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -2,6 +2,9 @@ Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. Written by Cygnus Support. +** NOTE: libcoff.h is a GENERATED file. Don't change it; instead, +** change libcoff-in.h or coffcode.h. + This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify @@ -405,6 +408,11 @@ struct coff_final_link_info long last_file_index; /* Contents of last C_FILE symbol. */ struct internal_syment last_file; + /* Symbol index of first aux entry of last .bf symbol with an empty + endndx field (-1 if none). */ + long last_bf_index; + /* Contents of last_bf_index aux entry. */ + union internal_auxent last_bf; /* Hash table used to merge debug information. */ struct coff_debug_merge_hash_table debug_merge; /* Buffer large enough to hold swapped symbols of any input file. */ @@ -814,7 +822,7 @@ typedef struct #define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ (obfd, info, ibfd, sec, rel, adjustedp)) -#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section, value, string, cp, coll, hashp)\ +#define bfd_coff_link_add_one_symbol(info,abfd,name,flags,section,value,string,cp,coll,hashp)\ ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ (info, abfd, name, flags, section, value, string, cp, coll, hashp)) diff --git a/bfd/peicode.h b/bfd/peicode.h index 4c0cf85..ccb445c 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -551,7 +551,7 @@ coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx); #endif - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) + if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) { in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext); in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext); @@ -637,7 +637,7 @@ coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx); #endif - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) + if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) { PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); |