GNU Binutils with patches for OS216
Revision | d6aa3fb01a1ea7ea24b205aa707fc2c72a80ad5d (tree) |
---|---|
Zeit | 1991-03-27 05:31:47 |
Autor | Steve Chamberlain <steve@cygn...> |
Commiter | Steve Chamberlain |
Fixes for ChrisB
@@ -19,28 +19,7 @@ You should have received a copy of the GNU General Public License along with | ||
19 | 19 | |
20 | 20 | /* $Id$ */ |
21 | 21 | /* |
22 | - FIXME-SOON. There is a major, potentially invalid assumption in this | |
23 | - code. Namely, that incoming symbol tables will be broken up and glued back | |
24 | - together but only on C_FILE boundaries. That is, if you break the symbol | |
25 | - table on some other boundary, or if you remove a single symbol in the | |
26 | - middle, it is possible to end up with garbage where you expect your | |
27 | - debugging info to be. This only affects debugging info. Specifically, it | |
28 | - affects all of the foondx's in the aux entries. C_FILE entries ARE glued | |
29 | - back together properly. Line numbers and relocations are tracked with | |
30 | - pointers so their ndx's aren't affected. | |
31 | - | |
32 | -On the other hand, if the symbol that a line number or reloc points to goes | |
33 | - away, or isn't included in an output bfd, then you'll end up with mush | |
34 | - anyway. | |
35 | - | |
36 | -I'm not sure at this point, (Sun Mar 3 00:56:11 PST 1991), but I suspect the | |
37 | - bfd library will need to provide at least the option of a higher and/or | |
38 | - lower abstraction for (at least debugging) symbols. The current | |
39 | - abstraction is sufficient for linking, nm, and very nearly for stripping, | |
40 | - but is nowhere near what would be needed for gas to create coff symbols or | |
41 | - for gdb to read them. | |
42 | - | |
43 | -xoxorich. | |
22 | +Most of this hacked by Steve Chamberlain, steve@cygnus.com | |
44 | 23 | */ |
45 | 24 | |
46 | 25 | #include "archures.h" /* Machine architectures and types */ |
@@ -235,7 +214,53 @@ set_index(symbol, idx) | ||
235 | 214 | symbol->value = idx; |
236 | 215 | } |
237 | 216 | |
217 | +#if 0 | |
218 | +/* move the section with the specified name to the front of the bfd */ | |
219 | +static void | |
220 | +coff_section_to_front(bfd_ptr, move_section_with_this_name) | |
221 | +bfd *bfd_ptr; | |
222 | +char *move_section_with_this_name; | |
223 | +{ | |
224 | + asection **section_ptr_ptr = &(bfd_ptr->sections); | |
225 | + while (*section_ptr_ptr != (asection *)NULL) | |
226 | + { | |
227 | + asection *section_ptr = *section_ptr_ptr; | |
228 | + if (strcmp(section_ptr->name, move_section_with_this_name) == 0) | |
229 | + { | |
230 | + | |
231 | + *section_ptr_ptr = section_ptr->next; | |
232 | + section_ptr->next = bfd_ptr->sections; | |
233 | + bfd_ptr->sections = section_ptr; | |
234 | + | |
235 | + /* Now run through them all and patch the indexes */ | |
236 | + { | |
237 | + unsigned int index = 0; | |
238 | + section_ptr = bfd_ptr->sections; | |
239 | + | |
240 | + while (section_ptr != (asection *)NULL) { | |
241 | + section_ptr->index = index; | |
242 | + index++; | |
243 | + section_ptr = section_ptr->next; | |
244 | + } | |
245 | + } | |
246 | + return; | |
247 | + | |
248 | + } | |
249 | + section_ptr_ptr = &(section_ptr->next); | |
250 | + } | |
251 | +} | |
238 | 252 | |
253 | +/* Reorder the sections to .text, .data, .bss */ | |
254 | +static | |
255 | +void | |
256 | +coff_section_reorder(abfd) | |
257 | +bfd *abfd; | |
258 | +{ | |
259 | + coff_section_to_front(abfd,".bss"); | |
260 | + coff_section_to_front(abfd,".data"); | |
261 | + coff_section_to_front(abfd,".text"); | |
262 | +} | |
263 | +#endif | |
239 | 264 | /* |
240 | 265 | initialize a section structure with information peculiar to this |
241 | 266 | particular implementation of coff |
@@ -246,7 +271,8 @@ coff_new_section_hook(abfd_ignore, section_ignore) | ||
246 | 271 | bfd *abfd_ignore; |
247 | 272 | asection *section_ignore; |
248 | 273 | { |
249 | - return true; | |
274 | + | |
275 | + return true; | |
250 | 276 | } |
251 | 277 | /* actually it makes itself and its children from the file headers */ |
252 | 278 | static boolean |
@@ -361,7 +387,7 @@ coff_real_object_p(abfd, nscns, opthdr) | ||
361 | 387 | tdata->raw_linenos = 0; |
362 | 388 | tdata->raw_syments = 0; |
363 | 389 | tdata->sym_filepos =0; |
364 | - | |
390 | + tdata->flags = filehdr->f_flags; | |
365 | 391 | if (nscns != 0) { |
366 | 392 | unsigned int i; |
367 | 393 | for (i = 0; i < nscns; i++) { |
@@ -440,17 +466,24 @@ coff_real_object_p(abfd, nscns, opthdr) | ||
440 | 466 | |
441 | 467 | return abfd->xvec; |
442 | 468 | } |
469 | + | |
470 | + | |
471 | +/* | |
472 | +Takes a bfd and a symbol, returns a pointer to the coff specific area | |
473 | +of the symbol if there is one. | |
474 | +*/ | |
443 | 475 | static coff_symbol_type * |
444 | 476 | coff_symbol_from(abfd, symbol) |
445 | 477 | bfd *abfd; |
446 | 478 | asymbol *symbol; |
447 | 479 | { |
448 | - return symbol->the_bfd->xvec->flavour == bfd_target_coff_flavour_enum | |
449 | - ? | |
450 | - (coff_symbol_type *) symbol | |
451 | - : | |
452 | - (coff_symbol_type *) NULL; | |
480 | + if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum) | |
481 | + return (coff_symbol_type *)NULL; | |
453 | 482 | |
483 | + if (symbol->the_bfd->tdata == (void *)NULL) | |
484 | + return (coff_symbol_type *)NULL; | |
485 | + | |
486 | + return (coff_symbol_type *) symbol; | |
454 | 487 | } |
455 | 488 | |
456 | 489 |
@@ -654,368 +687,402 @@ bfd *abfd; | ||
654 | 687 | } |
655 | 688 | |
656 | 689 | |
657 | -/* | |
658 | - run through the internal symbol table and make all the pointers and things | |
659 | - within the table point to the right places | |
660 | -*/ | |
690 | +/* | |
691 | +This procedure runs through the native entries in a coff symbol table | |
692 | +and links up all the elements which should point to one another, in | |
693 | +particular these are: | |
661 | 694 | |
662 | -static void | |
663 | -coff_mangle_symbols(abfd) | |
664 | - bfd *abfd; | |
665 | -{ | |
666 | - asymbol **p; | |
667 | - unsigned int native_index = 0; | |
695 | +strtag, entag and untags have an auxent endindex which points to the | |
696 | +first syment after the .eos. This is simple to do, we just keep a | |
697 | +pointer to the symbol with the most recent pending strtag and patch it | |
698 | +when we see the eos. This works since coff structs are never nested. | |
668 | 699 | |
669 | - unsigned int last_file_index = 0; | |
670 | - unsigned int limit = bfd_get_symcount(abfd); | |
671 | - SYMENT *last_file_symbol = (SYMENT *) NULL; | |
700 | +ISFCN type entries have an endindex which points to the next static or | |
701 | +extern in the table, thereby skipping the function contents. | |
702 | +The coff book says that an ISFCN's tagindex | |
703 | +points to the first .bf for the function, so far I havn't seen it | |
704 | +used. We do this using the same mechanism as strtags. | |
672 | 705 | |
673 | - /* Remember the bfd from the last symbol */ | |
674 | - bfd *last_bfd = (bfd *) NULL; | |
675 | - /* Remember the native from the last symbol */ | |
676 | - SYMENT *last_native = (SYMENT *) NULL; | |
706 | +Each file entry has a value which points to the next file entry, | |
707 | +the last file entry points to the first extern symbol in the table | |
708 | +which is not an ISFCN. | |
677 | 709 | |
710 | +Each .bb entry points to the matching .eb entry, but these are nested | |
711 | +so we keep a stack of them. | |
678 | 712 | |
679 | - preload_n_offset(abfd); | |
713 | +The tagndx of .eos items points to the strtag attached to them, this | |
714 | +is simply the last_tagndx again. | |
680 | 715 | |
681 | - p = abfd->outsymbols; | |
682 | - limit = bfd_get_symcount(abfd); | |
683 | - native_index = 0; | |
684 | - while (limit--) | |
685 | - { | |
686 | - coff_symbol_type *q = coff_symbol_from(abfd, *p); | |
687 | - if ((*p)->the_bfd != last_bfd) { | |
688 | - last_bfd = (*p)->the_bfd; | |
689 | - last_native = 0; | |
690 | - last_file_index = native_index; | |
691 | - } | |
716 | +The tagndx of items with type strtag point to the defining struct. | |
717 | +This bit is complicated; We know that a struct ref and def must be | |
718 | +within the same file, so all the natives will be in the same vector. | |
719 | +This means that we can subtracts two pointers and get the index | |
720 | +differences between to items, used to work out the true index of the | |
721 | +target. | |
692 | 722 | |
693 | - if (!q) { | |
694 | - native_index++; | |
695 | - } | |
696 | - else { | |
697 | - SYMENT *native = q->native; | |
698 | - if (native == (SYMENT *) NULL) { | |
699 | - native_index++; | |
700 | - } | |
701 | - else { | |
723 | +We store in the name field of each syment the actual native index | |
724 | +applied so we can dig it out through a pointer. | |
702 | 725 | |
703 | 726 | |
704 | - /* Alter the native representation */ | |
705 | - if (q->symbol.flags & BSF_FORT_COMM) { | |
706 | - native->n_scnum = 0; | |
707 | - native->n_value = q->symbol.value; | |
708 | - } | |
709 | - else if (q->symbol.flags & BSF_DEBUGGING) { | |
710 | - /* native->n_scnum = -2; */ | |
711 | - native->n_value = q->symbol.value; | |
712 | - } | |
713 | - else if (q->symbol.flags & BSF_UNDEFINED) { | |
714 | - native->n_scnum = 0; | |
715 | - native->n_value = 0; | |
716 | - } | |
717 | - else if (q->symbol.flags & BSF_ABSOLUTE) { | |
718 | - native->n_scnum = -1; | |
719 | - native->n_value = q->symbol.value; | |
720 | - } | |
721 | - else { | |
722 | - native->n_scnum = q->symbol.section->output_section->index + 1; | |
723 | - native->n_value = | |
724 | - q->symbol.value + | |
725 | - q->symbol.section->output_offset + | |
726 | - q->symbol.section->output_section->vma; | |
727 | - } | |
728 | - if (native->n_numaux != 0) | |
729 | - { | |
730 | - union auxent *a = (union auxent *) (native + 1); | |
731 | - | |
732 | - /* If this symbol forward references another, put | |
733 | - into it the real index of it by looking around | |
734 | - */ | |
735 | - if (uses_x_sym_x_fcnary_x_fcn_x_endndx_p(native)) | |
736 | - { | |
737 | - /* If this is a FCN entry without a | |
738 | - following .bf then we cheat and | |
739 | - insert the correct value directy. | |
740 | - */ | |
741 | - if (ISFCN(native->n_type) && | |
742 | - (native+2)->n_sclass != C_BLOCK) { | |
743 | - a->x_sym.x_fcnary.x_fcn.x_endndx = | |
744 | - native_index+ native->n_numaux + 1; | |
745 | - } | |
746 | - else{ | |
747 | - a->x_sym.x_fcnary.x_fcn.x_endndx = | |
748 | - new_idx(q,a->x_sym.x_fcnary.x_fcn.x_endndx); | |
749 | - } | |
750 | - | |
751 | - | |
752 | - } | |
753 | - if (uses_x_sym_x_tagndx_p(native)) { | |
754 | - a->x_sym.x_tagndx = | |
755 | - new_idx(q,a->x_sym.x_tagndx); | |
756 | - } | |
757 | -#ifdef I960 | |
758 | - else if (native->n_sclass == C_FCN | |
759 | - || !strcmp((char *) q->symbol.name, ".bf")) { | |
760 | - a->x_sym.x_fcnary.x_fcn.x_endndx = 0; | |
761 | - } | |
762 | -#endif /* I960 */ | |
763 | - | |
764 | - } | |
765 | - switch (native->n_sclass) { | |
766 | - case C_MOS: | |
767 | - case C_EOS: | |
768 | - case C_REGPARM: | |
769 | - case C_REG: | |
770 | -#ifdef C_AUTOARG | |
771 | - case C_AUTOARG: /* 960-specific storage class */ | |
772 | -#endif | |
773 | - /* | |
774 | - Fix so that they have an absolute section | |
775 | - */ | |
776 | - native->n_scnum = -1; | |
777 | - break; | |
778 | - | |
779 | - case C_FILE: | |
780 | - if (last_file_symbol) { | |
781 | - if (last_file_symbol->n_value != 0) { | |
782 | - abort(); | |
783 | - } /* sanity assertion */ | |
784 | - last_file_symbol->n_value = native_index; | |
785 | - } /* Chain all the .file symbols together */ | |
786 | - last_file_symbol = native; | |
787 | - | |
788 | - break; | |
789 | - | |
790 | - case C_EXT: | |
791 | - if (!ISFCN(native->n_type) | |
792 | - && last_file_symbol != NULL) { | |
793 | - if (last_file_symbol->n_value != 0) { | |
794 | - abort(); | |
795 | - } /* sanity assertion */ | |
796 | - last_file_symbol->n_value = native_index; | |
797 | - last_file_symbol = NULL; | |
798 | - } /* This should be the first global variable. */ | |
799 | - break; | |
800 | - | |
801 | - case C_FCN: | |
802 | - case C_NULL: | |
803 | - case C_AUTO: | |
804 | - case C_EXTDEF: | |
805 | - case C_LABEL: | |
806 | - case C_ULABEL: | |
807 | - case C_USTATIC: | |
808 | - case C_STRTAG: | |
809 | - case C_BLOCK: | |
810 | - case C_STAT: | |
811 | -#ifdef I960 | |
812 | - case C_LEAFEXT: | |
813 | - case C_LEAFSTAT: | |
814 | -#endif | |
815 | - break; | |
816 | - default: | |
817 | - /* | |
818 | - Bogus: This should be returning an error code, not | |
819 | - printing something out! | |
820 | - */ | |
821 | - /* | |
822 | - warning("Unrecognised sclass %d", native->n_sclass); | |
823 | - */ | |
824 | - break; | |
825 | - } | |
826 | - native_index += 1 + native->n_numaux; | |
727 | +*/ | |
728 | +static void | |
729 | +coff_mangle_symbols(bfd_ptr) | |
730 | +bfd *bfd_ptr; | |
731 | +{ | |
732 | + unsigned int symbol_count = bfd_get_symcount(bfd_ptr); | |
733 | + asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; | |
734 | + SYMENT *last_tagndx = (SYMENT *)NULL; | |
735 | + SYMENT *last_file = (SYMENT *)NULL; | |
736 | + SYMENT *last_fcn = (SYMENT *)NULL; | |
737 | + SYMENT *block_stack[50]; | |
738 | + SYMENT **last_block = &block_stack[0]; | |
739 | + boolean first_time = true; | |
740 | + unsigned int symbol_index; | |
741 | + unsigned int native_index = 0; | |
742 | + | |
743 | + for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) { | |
744 | + coff_symbol_type *coff_symbol_ptr = | |
745 | + coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]); | |
746 | + if (coff_symbol_ptr == (coff_symbol_type *)NULL) { | |
747 | + /* | |
748 | + This symbol has no coff information in it, it will take up | |
749 | + only one slot in the output symbol table | |
750 | + */ | |
751 | + native_index++; | |
752 | + } | |
753 | + else { | |
754 | + SYMENT *syment = coff_symbol_ptr->native; | |
755 | + if (syment == (SYMENT *)NULL) { | |
756 | + native_index++; | |
757 | + } | |
758 | + else { | |
759 | + /* Normalize the symbol flags */ | |
760 | + if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) { | |
761 | + /* a common symbol is undefined with a value */ | |
762 | + syment->n_scnum = N_UNDEF; | |
763 | + syment->n_value = coff_symbol_ptr->symbol.value; | |
764 | + } | |
765 | + else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) { | |
766 | + syment->n_value = coff_symbol_ptr->symbol.value; | |
767 | + } | |
768 | + else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) { | |
769 | + syment->n_scnum = N_UNDEF; | |
770 | + syment->n_value = 0; | |
771 | + } | |
772 | + else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) { | |
773 | + syment->n_scnum = N_ABS; | |
774 | + syment->n_value = coff_symbol_ptr->symbol.value; | |
775 | + } | |
776 | + else { | |
777 | + syment->n_scnum = | |
778 | + coff_symbol_ptr->symbol.section->output_section->index+1; | |
779 | + syment->n_value = | |
780 | + coff_symbol_ptr->symbol.value + | |
781 | + coff_symbol_ptr->symbol.section->output_offset + | |
782 | + coff_symbol_ptr->symbol.section->output_section->vma; | |
783 | + } | |
827 | 784 | |
828 | - /* Remember the last native here */ | |
829 | - last_native = native + native->n_numaux; | |
830 | - } | |
831 | 785 | |
786 | + /* If this symbol ties up something then do it */ | |
787 | + | |
788 | + if (syment->n_sclass == C_FILE && last_file != (SYMENT *)NULL) | |
789 | + { | |
790 | + last_file->n_value = native_index; | |
791 | + } | |
792 | + else if ((syment->n_sclass == C_EXT | |
793 | + || syment->n_sclass == C_STAT | |
794 | + || syment->n_sclass == C_LEAFEXT | |
795 | + || syment->n_sclass == C_LEAFSTAT) | |
796 | + && last_fcn != (SYMENT *)NULL) | |
797 | + { | |
798 | + AUXENT *auxent = (AUXENT *)(last_fcn+1); | |
799 | + auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index; | |
800 | + last_fcn = (SYMENT *)NULL; | |
801 | + | |
802 | + } | |
803 | + else if (syment->n_sclass == C_EOS && last_tagndx != (SYMENT*)NULL) | |
804 | + { | |
805 | + AUXENT *auxent = (AUXENT *)(last_tagndx+1); | |
806 | + /* Remember that we keep the native index in the offset | |
807 | + so patch the beginning of the struct to point to this | |
808 | + */ | |
809 | + auxent->x_sym.x_tagndx = last_tagndx->n_offset; | |
810 | + auxent->x_sym.x_fcnary.x_fcn.x_endndx = | |
811 | + native_index + syment->n_numaux + 1 ; | |
812 | + /* Now point the eos to the structure */ | |
813 | + auxent = (AUXENT *)(syment+1); | |
814 | + auxent->x_sym.x_tagndx = last_tagndx->n_offset; | |
815 | + | |
816 | + | |
817 | + } | |
818 | + else if (syment->n_sclass == C_BLOCK | |
819 | + && coff_symbol_ptr->symbol.name[1] == 'e') | |
820 | + { | |
821 | + AUXENT *auxent = (AUXENT *)((*(--last_block))+1); | |
822 | + auxent->x_sym.x_fcnary.x_fcn.x_endndx = | |
823 | + native_index + syment->n_numaux + 1; | |
824 | + } | |
825 | + if (syment->n_sclass == C_EXT | |
826 | + && !ISFCN(syment->n_type) | |
827 | + && first_time == true | |
828 | + && last_file != (SYMENT *)NULL) { | |
829 | + /* This is the first external symbol seen which isn't a | |
830 | + function place it in the last .file entry */ | |
831 | + last_file->n_value = native_index; | |
832 | + first_time = false; | |
833 | + } | |
834 | + if (syment->n_sclass == C_LEAFPROC && syment->n_numaux == 2) { | |
835 | + AUXENT *auxent = (AUXENT *)(syment+2); | |
836 | + /* This is the definition of a leaf proc, we'll relocate the | |
837 | + address */ | |
838 | + | |
839 | + auxent->x_bal.x_balntry += | |
840 | + coff_symbol_ptr->symbol.section->output_offset + | |
841 | + coff_symbol_ptr->symbol.section->output_section->vma ; | |
842 | + } | |
843 | + /* If this symbol needs to be tied up then remember some facts */ | |
844 | + if (syment->n_sclass == C_FILE) | |
845 | + { | |
846 | + last_file = syment; | |
847 | + } | |
848 | + if (syment->n_numaux != 0) { | |
849 | + /* | |
850 | + If this symbol would like to point to something in the | |
851 | + future then remember where it is | |
852 | + */ | |
853 | + if (uses_x_sym_x_tagndx_p(syment)) { | |
854 | + /* | |
855 | + If this is a ref to a structure then we'll tie it up | |
856 | + now - there are never any forward refs for one | |
857 | + */ | |
858 | + if (syment->n_sclass == C_STRTAG || | |
859 | + syment->n_sclass == C_ENTAG || | |
860 | + syment->n_sclass == C_UNTAG) { | |
861 | + last_tagndx = syment; | |
832 | 862 | } |
863 | + else { | |
864 | + /* | |
865 | + This is a ref to a structure - the structure must | |
866 | + have been defined within the same file, and previous | |
867 | + to this point, so we can deduce the new tagndx | |
868 | + directly. | |
869 | + */ | |
870 | + AUXENT *auxent = (AUXENT *)(syment+1); | |
871 | + bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd; | |
872 | + SYMENT *base = obj_raw_syments(bfd_ptr); | |
873 | + auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx].n_offset; | |
833 | 874 | |
834 | - p++; | |
875 | + } | |
876 | + } | |
877 | + if (ISFCN(syment->n_type)) { | |
878 | + last_fcn = syment; | |
879 | + } | |
880 | + if (syment->n_sclass == C_BLOCK | |
881 | + && coff_symbol_ptr->symbol.name[1] == 'b') | |
882 | + { | |
883 | + *last_block++ = syment; | |
884 | + } | |
835 | 885 | } |
836 | - | |
886 | + syment->n_offset = native_index; | |
887 | + native_index = native_index + 1 + syment->n_numaux; | |
888 | + } | |
889 | + } | |
890 | + } | |
837 | 891 | } |
892 | + | |
893 | + | |
894 | + | |
838 | 895 | |
896 | + | |
897 | + | |
839 | 898 | |
840 | 899 | static void |
841 | 900 | coff_write_symbols(abfd) |
842 | 901 | bfd *abfd; |
843 | 902 | { |
844 | - unsigned int i; | |
845 | - unsigned int limit = bfd_get_symcount(abfd); | |
846 | - unsigned int written = 0; | |
847 | - SYMENT dummy; | |
848 | - asymbol **p; | |
849 | - unsigned int string_size = 0; | |
850 | - | |
851 | - | |
852 | - /* Seek to the right place */ | |
853 | - bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET); | |
854 | - | |
855 | - /* Output all the symbols we have */ | |
856 | - | |
857 | - written = 0; | |
858 | - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { | |
859 | - asymbol *symbol = *p; | |
860 | - coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol); | |
861 | - | |
862 | - unsigned int j; | |
863 | - SYMENT *native; | |
864 | - if (c_symbol == (coff_symbol_type *) NULL || | |
865 | - c_symbol->native == (SYMENT *) NULL) { | |
866 | - /* | |
867 | - This symbol has been created by the loader, or come from a non | |
868 | - coff format. It has no native element to inherit, make our | |
869 | - own | |
870 | - */ | |
871 | - native = &dummy; | |
872 | - native->n_type = T_NULL; | |
873 | - if (symbol->flags & BSF_ABSOLUTE) { | |
874 | - native->n_scnum = N_ABS; | |
875 | - native->n_value = symbol->value; | |
876 | - } | |
877 | - else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) { | |
878 | - native->n_scnum = N_UNDEF; | |
879 | - native->n_value = symbol->value; | |
880 | - } | |
881 | - else if (symbol->flags & BSF_DEBUGGING) { | |
882 | - /* | |
883 | - remove name so it doesn't take up any space | |
884 | - */ | |
885 | - symbol->name = ""; | |
903 | + unsigned int i; | |
904 | + unsigned int limit = bfd_get_symcount(abfd); | |
905 | + unsigned int written = 0; | |
906 | + SYMENT dummy; | |
907 | + asymbol **p; | |
908 | + unsigned int string_size = 0; | |
909 | + | |
910 | + | |
911 | + /* Seek to the right place */ | |
912 | + bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET); | |
913 | + | |
914 | + /* Output all the symbols we have */ | |
915 | + | |
916 | + written = 0; | |
917 | + for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { | |
918 | + asymbol *symbol = *p; | |
919 | + coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol); | |
920 | + | |
921 | + unsigned int j; | |
922 | + SYMENT *native; | |
923 | + if (c_symbol == (coff_symbol_type *) NULL || | |
924 | + c_symbol->native == (SYMENT *) NULL) { | |
925 | + /* | |
926 | + This symbol has been created by the loader, or come from a non | |
927 | + coff format. It has no native element to inherit, make our | |
928 | + own | |
929 | + */ | |
930 | + | |
931 | + native = &dummy; | |
932 | + native->n_type = T_NULL; | |
933 | +#ifdef I960 | |
934 | + native->n_flags = 0; | |
935 | +#endif | |
936 | + if (symbol->flags & BSF_ABSOLUTE) { | |
937 | + native->n_scnum = N_ABS; | |
938 | + native->n_value = symbol->value; | |
939 | + } | |
940 | + else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) { | |
941 | + native->n_scnum = N_UNDEF; | |
942 | + native->n_value = symbol->value; | |
943 | + } | |
944 | + else if (symbol->flags & BSF_DEBUGGING) { | |
945 | + /* | |
946 | + remove name so it doesn't take up any space | |
947 | + */ | |
948 | + symbol->name = ""; | |
886 | 949 | #if 0 /* FIXME -- Steve hasn't decided what to do |
887 | 950 | with these */ |
888 | - /* | |
889 | - Don't do anything with debugs from the loader | |
890 | - */ | |
891 | - native->n_scnum = N_DEBUG; | |
951 | + /* | |
952 | + Don't do anything with debugs from the loader | |
953 | + */ | |
954 | + native->n_scnum = N_DEBUG; | |
892 | 955 | #endif |
893 | - continue; | |
894 | - } | |
895 | - else { | |
896 | - native->n_scnum = symbol->section->output_section->index + 1; | |
897 | - native->n_value = symbol->value + | |
898 | - symbol->section->output_section->vma + | |
899 | - symbol->section->output_offset; | |
900 | - } | |
901 | - | |
956 | + continue; | |
957 | + } | |
958 | + else { | |
959 | + native->n_scnum = symbol->section->output_section->index + 1; | |
960 | + native->n_value = symbol->value + | |
961 | + symbol->section->output_section->vma + | |
962 | + symbol->section->output_offset; | |
902 | 963 | #ifdef I960 |
903 | - /* | |
904 | - FIXME-SOON: THIS IS ALREADY WRONG FOR I960. Should echo the | |
905 | - flags in the filehdr. (?) | |
906 | - */ | |
907 | - native->n_flags = 0; | |
908 | -#else /* else not I960 */ | |
909 | -#ifdef HASPAD1 | |
910 | - native->pad1[0] = 0; | |
911 | - native->pad1[0] = 0; | |
964 | + /* Copy the any flags from the the file hdr into the symbol */ | |
965 | + { | |
966 | + coff_symbol_type *c = coff_symbol_from(abfd, symbol); | |
967 | + if (c != (coff_symbol_type *)NULL) { | |
968 | + native->n_flags = c->symbol.the_bfd->flags; | |
969 | + } | |
970 | + } | |
912 | 971 | #endif |
913 | -#endif /* I960 */ | |
914 | - native->pad2[0] = 0; | |
915 | - native->pad2[1] = 0; | |
916 | - | |
917 | - native->n_type = 0; | |
918 | - native->n_sclass = C_EXT; | |
919 | - native->n_numaux = 0; | |
920 | 972 | } |
921 | - else | |
922 | - /* | |
923 | - Does this symbol have an ascociated line number - if so then | |
924 | - make it remember this symbol index. Also tag the auxent of | |
925 | - this symbol to point to the right place in the lineno table | |
926 | - */ | |
927 | - { | |
928 | - alent *lineno = c_symbol->lineno; | |
929 | - native = c_symbol->native; | |
930 | - if (lineno) { | |
931 | - unsigned int count = 0; | |
932 | - lineno[count].u.offset = written; | |
933 | - if (native->n_numaux) { | |
934 | - union auxent *a = (union auxent *) (native + 1); | |
935 | - a->x_sym.x_fcnary.x_fcn.x_lnnoptr = | |
936 | - c_symbol->symbol.section->output_section->moving_line_filepos; | |
937 | - } | |
938 | - /* | |
939 | - And count and relocate all other linenumbers | |
940 | - */ | |
941 | - count++; | |
942 | - while (lineno[count].line_number) { | |
943 | - lineno[count].u.offset += | |
944 | - c_symbol->symbol.section->output_section->vma + | |
945 | - c_symbol->symbol.section->output_offset; | |
946 | - count++; | |
947 | - } | |
948 | - c_symbol->symbol.section->output_section->moving_line_filepos += | |
949 | - count * sizeof(struct lineno); | |
950 | 973 | |
951 | - } | |
952 | - } /* if symbol new to coff */ | |
953 | 974 | |
954 | - /* Fix the symbol names */ | |
955 | - { | |
956 | - unsigned int name_length; | |
957 | - if (symbol->name == (char *) NULL) { | |
958 | - /* | |
959 | - coff symbols always have names, so we'll make one up | |
960 | - */ | |
961 | - symbol->name = "strange"; | |
962 | - } | |
963 | - name_length = strlen(symbol->name); | |
964 | - if (name_length <= SYMNMLEN) { | |
965 | - /* This name will fit into the symbol neatly */ | |
966 | - strncpy(native->n_name, symbol->name, SYMNMLEN); | |
967 | - } | |
968 | - else { | |
969 | - native->n_offset = string_size + 4; | |
970 | - native->n_zeroes = 0; | |
971 | - string_size += name_length + 1; | |
972 | - } | |
973 | - { | |
974 | - unsigned int numaux = native->n_numaux; | |
975 | - int type = native->n_type; | |
976 | - int class = native->n_sclass; | |
977 | - bfd_coff_swap_sym(abfd, native); | |
978 | - bfd_write((void *) native, 1, SYMESZ, abfd); | |
979 | - for (j = 0; j != native->n_numaux; j++) { | |
980 | - bfd_coff_swap_aux(abfd, native + j + 1, type, class); | |
981 | - bfd_write((void *) (native + j + 1), 1, AUXESZ, abfd); | |
982 | 975 | |
983 | - } | |
984 | - /* | |
985 | - Reuse somewhere in the symbol to keep the index | |
986 | - */ | |
987 | - set_index(symbol, written); | |
988 | - written += 1 + numaux; | |
989 | - } | |
976 | +#ifdef HASPAD1 | |
977 | + native->pad1[0] = 0; | |
978 | + native->pad1[0] = 0; | |
979 | +#endif | |
980 | + | |
981 | + native->pad2[0] = 0; | |
982 | + native->pad2[1] = 0; | |
983 | + | |
984 | + native->n_type = 0; | |
985 | + native->n_sclass = C_EXT; | |
986 | + native->n_numaux = 0; | |
987 | + } | |
988 | + else | |
989 | + /* | |
990 | + Does this symbol have an ascociated line number - if so then | |
991 | + make it remember this symbol index. Also tag the auxent of | |
992 | + this symbol to point to the right place in the lineno table | |
993 | + */ | |
994 | + { | |
995 | + alent *lineno = c_symbol->lineno; | |
996 | + native = c_symbol->native; | |
997 | + if (lineno) { | |
998 | + unsigned int count = 0; | |
999 | + lineno[count].u.offset = written; | |
1000 | + if (native->n_numaux) { | |
1001 | + union auxent *a = (union auxent *) (native + 1); | |
1002 | + a->x_sym.x_fcnary.x_fcn.x_lnnoptr = | |
1003 | + c_symbol->symbol.section->output_section->moving_line_filepos; | |
1004 | + } | |
1005 | + /* | |
1006 | + And count and relocate all other linenumbers | |
1007 | + */ | |
1008 | + count++; | |
1009 | + while (lineno[count].line_number) { | |
1010 | + lineno[count].u.offset += | |
1011 | + c_symbol->symbol.section->output_section->vma + | |
1012 | + c_symbol->symbol.section->output_offset; | |
1013 | + count++; | |
1014 | + } | |
1015 | + c_symbol->symbol.section->output_section->moving_line_filepos += | |
1016 | + count * sizeof(struct lineno); | |
1017 | + | |
990 | 1018 | } |
991 | - } /* for each out symbol */ | |
992 | - | |
993 | - bfd_get_symcount(abfd) = written; | |
994 | - /* Now write out strings */ | |
995 | - | |
996 | - if (string_size) { | |
997 | - unsigned int size = string_size + 4; | |
998 | - bfd_h_put_x(abfd, size, &size); | |
999 | - bfd_write((void *) &size, 1, sizeof(size), abfd); | |
1000 | - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { | |
1001 | - asymbol *q = *p; | |
1002 | - size_t name_length = strlen(q->name); | |
1003 | - if (name_length > SYMNMLEN) { | |
1004 | - bfd_write((void *) (q->name), 1, name_length + 1, abfd); | |
1005 | - } | |
1019 | + } /* if symbol new to coff */ | |
1020 | + | |
1021 | + /* Fix the symbol names */ | |
1022 | + { | |
1023 | + unsigned int name_length; | |
1024 | + if (symbol->name == (char *) NULL) { | |
1025 | + /* | |
1026 | + coff symbols always have names, so we'll make one up | |
1027 | + */ | |
1028 | + symbol->name = "strange"; | |
1029 | + } | |
1030 | + name_length = strlen(symbol->name); | |
1031 | + if (name_length <= SYMNMLEN) { | |
1032 | + /* This name will fit into the symbol neatly */ | |
1033 | + strncpy(native->n_name, symbol->name, SYMNMLEN); | |
1034 | + } | |
1035 | + else { | |
1036 | + native->n_offset = string_size + 4; | |
1037 | + native->n_zeroes = 0; | |
1038 | + string_size += name_length + 1; | |
1039 | + } | |
1040 | + { | |
1041 | + unsigned int numaux = native->n_numaux; | |
1042 | + int type = native->n_type; | |
1043 | + int class = native->n_sclass; | |
1044 | + bfd_coff_swap_sym(abfd, native); | |
1045 | + bfd_write((void *) native, 1, SYMESZ, abfd); | |
1046 | + for (j = 0; j != native->n_numaux; j++) { | |
1047 | + bfd_coff_swap_aux(abfd, native + j + 1, type, class); | |
1048 | + bfd_write((void *) (native + j + 1), 1, AUXESZ, abfd); | |
1049 | + | |
1006 | 1050 | } |
1007 | - } | |
1008 | - else { | |
1009 | - /* We would normally not write anything here, but we'll write | |
1010 | - out 4 so that any stupid coff reader which tries to read | |
1011 | - the string table even when there isn't one won't croak. | |
1051 | + /* | |
1052 | + Reuse somewhere in the symbol to keep the index | |
1012 | 1053 | */ |
1054 | + set_index(symbol, written); | |
1055 | + written += 1 + numaux; | |
1056 | + } | |
1057 | + } | |
1058 | + } /* for each out symbol */ | |
1013 | 1059 | |
1014 | - uint32e_type size = 4; | |
1015 | - bfd_h_put_x(abfd, size, &size); | |
1016 | - bfd_write((void *)&size, 1, sizeof(size), abfd); | |
1017 | - | |
1060 | + bfd_get_symcount(abfd) = written; | |
1061 | + /* Now write out strings */ | |
1062 | + | |
1063 | + if (string_size) { | |
1064 | + unsigned int size = string_size + 4; | |
1065 | + bfd_h_put_x(abfd, size, &size); | |
1066 | + bfd_write((void *) &size, 1, sizeof(size), abfd); | |
1067 | + for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { | |
1068 | + asymbol *q = *p; | |
1069 | + size_t name_length = strlen(q->name); | |
1070 | + if (name_length > SYMNMLEN) { | |
1071 | + bfd_write((void *) (q->name), 1, name_length + 1, abfd); | |
1072 | + } | |
1018 | 1073 | } |
1074 | + } | |
1075 | + else { | |
1076 | + /* We would normally not write anything here, but we'll write | |
1077 | + out 4 so that any stupid coff reader which tries to read | |
1078 | + the string table even when there isn't one won't croak. | |
1079 | + */ | |
1080 | + | |
1081 | + uint32e_type size = 4; | |
1082 | + bfd_h_put_x(abfd, size, &size); | |
1083 | + bfd_write((void *)&size, 1, sizeof(size), abfd); | |
1084 | + | |
1085 | + } | |
1019 | 1086 | |
1020 | 1087 | } |
1021 | 1088 |
@@ -1253,6 +1320,9 @@ coff_compute_section_file_positions(abfd) | ||
1253 | 1320 | obj_relocbase(abfd) = sofar; |
1254 | 1321 | } |
1255 | 1322 | |
1323 | + | |
1324 | + | |
1325 | + | |
1256 | 1326 | /* SUPPRESS 558 */ |
1257 | 1327 | /* SUPPRESS 529 */ |
1258 | 1328 | static boolean |
@@ -1289,6 +1359,9 @@ coff_write_object_contents(abfd) | ||
1289 | 1359 | reloc_base = obj_relocbase(abfd); |
1290 | 1360 | |
1291 | 1361 | |
1362 | + | |
1363 | + | |
1364 | + | |
1292 | 1365 | /* |
1293 | 1366 | Make a pass through the symbol table to count line number entries and |
1294 | 1367 | put them into the correct asections |
@@ -2454,108 +2527,120 @@ coff_find_nearest_line(abfd, | ||
2454 | 2527 | char **functionname_ptr; |
2455 | 2528 | unsigned int *line_ptr; |
2456 | 2529 | { |
2457 | - static bfd *cache_abfd; | |
2458 | - static asection *cache_section; | |
2459 | - static bfd_vma cache_offset; | |
2460 | - static unsigned int cache_i; | |
2461 | - static alent *cache_l; | |
2462 | - | |
2463 | - unsigned int i = 0; | |
2464 | - struct icofdata *cof = obj_icof(abfd); | |
2465 | - /* Run through the raw syments if available */ | |
2466 | - SYMENT *p = cof->raw_syments; | |
2467 | - alent *l; | |
2468 | - unsigned int line_base = 0; | |
2469 | - *filename_ptr = 0; | |
2470 | - *functionname_ptr = 0; | |
2471 | - *line_ptr = 0; | |
2472 | - /* | |
2473 | - I don't know for sure what's right, but this isn't it. First off, an | |
2474 | - object file may not have any C_FILE's in it. After | |
2475 | - get_normalized_symtab(), it should have at least 1, the one I put | |
2476 | - there, but otherwise, all bets are off. Point #2, the first C_FILE | |
2477 | - isn't necessarily the right C_FILE because any given object may have | |
2478 | - many. I think you'll have to track sections as they coelesce in order | |
2479 | - to find the C_STAT symbol for this section. Then you'll have to work | |
2480 | - backwards to find the previous C_FILE, or choke if you get to a C_STAT | |
2481 | - for the same kind of section. That will mean that the original object | |
2482 | - file didn't have a C_FILE. xoxorich. | |
2483 | - */ | |
2484 | - | |
2485 | -#ifdef WEREBEINGPEDANTIC | |
2530 | + static bfd *cache_abfd; | |
2531 | + static asection *cache_section; | |
2532 | + static bfd_vma cache_offset; | |
2533 | + static unsigned int cache_i; | |
2534 | + static alent *cache_l; | |
2535 | + | |
2536 | + unsigned int i = 0; | |
2537 | + struct icofdata *cof = obj_icof(abfd); | |
2538 | + /* Run through the raw syments if available */ | |
2539 | + SYMENT *p; | |
2540 | + alent *l; | |
2541 | + unsigned int line_base = 0; | |
2542 | + | |
2543 | + | |
2544 | + *filename_ptr = 0; | |
2545 | + *functionname_ptr = 0; | |
2546 | + *line_ptr = 0; | |
2547 | + | |
2548 | + /* Don't try and find line numbers in a non coff file */ | |
2549 | + if (abfd->xvec->flavour != bfd_target_coff_flavour_enum) | |
2486 | 2550 | return false; |
2487 | -#endif | |
2488 | - | |
2489 | 2551 | |
2552 | + if (cof == (struct icofdata *)NULL) | |
2553 | + return false; | |
2490 | 2554 | |
2491 | - for (i = 0; i < cof->raw_syment_count; i++) { | |
2492 | - if (p->n_sclass == C_FILE) { | |
2493 | - /* File name is embeded in auxent */ | |
2494 | - /* | |
2495 | - This isn't right. The fname should probably be normalized | |
2496 | - during get_normalized_symtab(). In any case, what was here | |
2497 | - wasn't right because a SYMENT.n_name isn't an | |
2498 | - AUXENT.x_file.x_fname. xoxorich. | |
2499 | - */ | |
2555 | + | |
2556 | + p = cof->raw_syments; | |
2557 | + /* | |
2558 | + I don't know for sure what's right, but this isn't it. First off, an | |
2559 | + object file may not have any C_FILE's in it. After | |
2560 | + get_normalized_symtab(), it should have at least 1, the one I put | |
2561 | + there, but otherwise, all bets are off. Point #2, the first C_FILE | |
2562 | + isn't necessarily the right C_FILE because any given object may have | |
2563 | + many. I think you'll have to track sections as they coelesce in order | |
2564 | + to find the C_STAT symbol for this section. Then you'll have to work | |
2565 | + backwards to find the previous C_FILE, or choke if you get to a C_STAT | |
2566 | + for the same kind of section. That will mean that the original object | |
2567 | + file didn't have a C_FILE. xoxorich. | |
2568 | + */ | |
2500 | 2569 | |
2501 | - *filename_ptr = ((AUXENT *) (p + 1))->x_file.x_fname; | |
2502 | - break; | |
2503 | - } | |
2504 | - p += 1 + p->n_numaux; | |
2505 | - } | |
2506 | - /* Now wander though the raw linenumbers of the section */ | |
2570 | +#ifdef WEREBEINGPEDANTIC | |
2571 | + return false; | |
2572 | +#endif | |
2507 | 2573 | |
2508 | 2574 | |
2509 | 2575 | |
2576 | + for (i = 0; i < cof->raw_syment_count; i++) { | |
2577 | + if (p->n_sclass == C_FILE) { | |
2578 | + /* File name is embeded in auxent */ | |
2579 | + /* | |
2580 | + This isn't right. The fname should probably be normalized | |
2581 | + during get_normalized_symtab(). In any case, what was here | |
2582 | + wasn't right because a SYMENT.n_name isn't an | |
2583 | + AUXENT.x_file.x_fname. xoxorich. | |
2584 | + */ | |
2510 | 2585 | |
2511 | - /* | |
2512 | - If this is the same bfd as we were previously called with and this is | |
2513 | - the same section, and the offset we want is further down then we can | |
2514 | - prime the lookup loop | |
2515 | - */ | |
2516 | - if (abfd == cache_abfd && | |
2517 | - section == cache_section && | |
2518 | - offset >= cache_offset) { | |
2519 | - i = cache_i; | |
2520 | - l = cache_l; | |
2521 | - } | |
2522 | - else { | |
2523 | - i = 0; | |
2524 | - l = section->lineno; | |
2586 | + *filename_ptr = ((AUXENT *) (p + 1))->x_file.x_fname; | |
2587 | + break; | |
2525 | 2588 | } |
2526 | - | |
2527 | - for (; i < section->lineno_count; i++) { | |
2528 | - if (l->line_number == 0) { | |
2529 | - /* Get the symbol this line number points at */ | |
2530 | - coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); | |
2531 | - *functionname_ptr = coff->symbol.name; | |
2532 | - if (coff->native) { | |
2533 | - struct syment *s = coff->native; | |
2534 | - s = s + 1 + s->n_numaux; | |
2535 | - /* | |
2536 | - S should now point to the .bf of the function | |
2537 | - */ | |
2538 | - if (s->n_numaux) { | |
2539 | - /* | |
2540 | - The linenumber is stored in the auxent | |
2541 | - */ | |
2542 | - union auxent *a = (union auxent *) (s + 1); | |
2543 | - line_base = a->x_sym.x_misc.x_lnsz.x_lnno; | |
2544 | - } | |
2545 | - } | |
2546 | - } | |
2547 | - else { | |
2548 | - if (l->u.offset > offset) | |
2549 | - break; | |
2550 | - *line_ptr = l->line_number + line_base + 1; | |
2589 | + p += 1 + p->n_numaux; | |
2590 | + } | |
2591 | + /* Now wander though the raw linenumbers of the section */ | |
2592 | + | |
2593 | + | |
2594 | + | |
2595 | + | |
2596 | + /* | |
2597 | + If this is the same bfd as we were previously called with and this is | |
2598 | + the same section, and the offset we want is further down then we can | |
2599 | + prime the lookup loop | |
2600 | + */ | |
2601 | + if (abfd == cache_abfd && | |
2602 | + section == cache_section && | |
2603 | + offset >= cache_offset) { | |
2604 | + i = cache_i; | |
2605 | + l = cache_l; | |
2606 | + } | |
2607 | + else { | |
2608 | + i = 0; | |
2609 | + l = section->lineno; | |
2610 | + } | |
2611 | + | |
2612 | + for (; i < section->lineno_count; i++) { | |
2613 | + if (l->line_number == 0) { | |
2614 | + /* Get the symbol this line number points at */ | |
2615 | + coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); | |
2616 | + *functionname_ptr = coff->symbol.name; | |
2617 | + if (coff->native) { | |
2618 | + struct syment *s = coff->native; | |
2619 | + s = s + 1 + s->n_numaux; | |
2620 | + /* | |
2621 | + S should now point to the .bf of the function | |
2622 | + */ | |
2623 | + if (s->n_numaux) { | |
2624 | + /* | |
2625 | + The linenumber is stored in the auxent | |
2626 | + */ | |
2627 | + union auxent *a = (union auxent *) (s + 1); | |
2628 | + line_base = a->x_sym.x_misc.x_lnsz.x_lnno; | |
2551 | 2629 | } |
2552 | - l++; | |
2630 | + } | |
2553 | 2631 | } |
2554 | - | |
2555 | - cache_abfd = abfd; | |
2556 | - cache_section = section; | |
2557 | - cache_offset = offset; | |
2558 | - cache_i = i; | |
2559 | - cache_l = l; | |
2560 | - return true; | |
2632 | + else { | |
2633 | + if (l->u.offset > offset) | |
2634 | + break; | |
2635 | + *line_ptr = l->line_number + line_base + 1; | |
2636 | + } | |
2637 | + l++; | |
2638 | + } | |
2639 | + | |
2640 | + cache_abfd = abfd; | |
2641 | + cache_section = section; | |
2642 | + cache_offset = offset; | |
2643 | + cache_i = i; | |
2644 | + cache_l = l; | |
2645 | + return true; | |
2561 | 2646 | } |