From 45a78ebbfb8942d9fea9702c9956be8621eac71a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 31 Aug 1993 17:28:03 +0000 Subject: [PATCH] * nlmcode.h (nlm_object_p): Set HAS_SYMS if there are external references. (nlm_swap_auxiliary_headers_{in,out}): The copyright length is only one byte. (nlm_get_symtab_upper_bound): Include debugging symbols in symbol count. (nlm_slurp_symbol_table): Make symlength unsigned. Read debugging symbols as BFD local symbols. (nlm_write_object_contents): Don't bother writing out exported symbols more than once; they now appear in the symbol table more than once (with and without a prefix) if necessary. Set offset values to be non-zero as NLMLINK does. --- bfd/ChangeLog | 15 +++ bfd/nlmcode.h | 345 ++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 220 insertions(+), 140 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 12beae3..8be38d7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +Tue Aug 31 12:50:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * nlmcode.h (nlm_object_p): Set HAS_SYMS if there are external + references. + (nlm_swap_auxiliary_headers_{in,out}): The copyright length is + only one byte. + (nlm_get_symtab_upper_bound): Include debugging symbols in symbol + count. + (nlm_slurp_symbol_table): Make symlength unsigned. Read debugging + symbols as BFD local symbols. + (nlm_write_object_contents): Don't bother writing out exported + symbols more than once; they now appear in the symbol table more + than once (with and without a prefix) if necessary. Set offset + values to be non-zero as NLMLINK does. + Tue Aug 31 12:07:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com) * libhppa.h: Restore #undefs of e_fsel and other e_* symbols. diff --git a/bfd/nlmcode.h b/bfd/nlmcode.h index 31c5dec..7944d5f 100644 --- a/bfd/nlmcode.h +++ b/bfd/nlmcode.h @@ -109,7 +109,6 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd) if (strncmp (x_fxdhdr.signature, NLM_SIGNATURE, NLM_SIGNATURE_SIZE) != 0) { - wrong: bfd_error = wrong_format; return (NULL); } @@ -120,14 +119,18 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd) if (get_word (abfd, (bfd_byte *) x_fxdhdr.version) > 0xFFFF) { - goto wrong; + bfd_error = wrong_format; + return (NULL); } /* There's no supported way to check for 32 bit versus 64 bit addresses, so ignore this distinction for now. (FIXME) */ /* Allocate an instance of the nlm_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ + the tdata pointer in the bfd. + FIXME: If we later decide this isn't the right format and the bfd + already had valid tdata, we've just blown away the tdata we wanted + to save for the right format. */ nlm_tdata (abfd) = (struct nlm_obj_tdata *) bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)); @@ -137,7 +140,9 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd) return (NULL); } - /* FIXME: Any `wrong' exits below here will leak memory (tdata). */ + /* FIXME: Any return(NULL) exits below here will leak memory (tdata). + And a memory leak also means we lost the real tdata info we wanted + to save, because it was in the leaked memory. */ /* Swap in the rest of the fixed length header. */ @@ -161,6 +166,7 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd) i_fxdhdrp -> uninitializedDataSize, SEC_ALLOC)) { + bfd_error = wrong_format; return (NULL); } @@ -168,7 +174,8 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd) || nlm_fixed_header (abfd)->numberOfExternalReferences != 0) abfd->flags |= HAS_RELOC; if (nlm_fixed_header (abfd)->numberOfPublics != 0 - || nlm_fixed_header (abfd)->numberOfDebugRecords != 0) + || nlm_fixed_header (abfd)->numberOfDebugRecords != 0 + || nlm_fixed_header (abfd)->numberOfExternalReferences != 0) abfd->flags |= HAS_SYMS; arch = nlm_architecture (abfd); @@ -655,15 +662,21 @@ DEFUN (nlm_swap_auxiliary_headers_in, (abfd), else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0) { Nlm_External_Copyright_Header thdr; - if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) + if (bfd_read ((PTR) &nlm_copyright_header (abfd)->stamp, + sizeof (nlm_copyright_header (abfd)->stamp), + 1, abfd) + != sizeof (nlm_copyright_header (abfd)->stamp)) + { + bfd_error = system_call_error; + return (false); + } + if (bfd_read ((PTR) &(nlm_copyright_header (abfd) + ->copyrightMessageLength), + 1, 1, abfd) != 1) { bfd_error = system_call_error; return (false); } - memcpy (nlm_copyright_header (abfd) -> stamp, thdr.stamp, - sizeof (thdr.stamp)); - nlm_copyright_header (abfd) -> copyrightMessageLength = - get_word (abfd, (bfd_byte *) thdr.copyrightMessageLength); /* The copyright message is a variable length string. */ if (bfd_read ((PTR) nlm_copyright_header (abfd) -> copyrightMessage, nlm_copyright_header (abfd) -> copyrightMessageLength + 1, @@ -857,14 +870,19 @@ nlm_swap_auxiliary_headers_out (abfd) Nlm_External_Copyright_Header thdr; memcpy (thdr.stamp, "CoPyRiGhT=", 10); - put_word (abfd, - (bfd_vma) nlm_copyright_header (abfd) -> copyrightMessageLength, - (bfd_byte *) thdr.copyrightMessageLength); - if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - { - bfd_error = system_call_error; - return false; - } + if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd) + != sizeof (thdr.stamp)) + { + bfd_error = system_call_error; + return false; + } + thdr.copyrightMessageLength[0] = + nlm_copyright_header (abfd)->copyrightMessageLength; + if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1) + { + bfd_error = system_call_error; + return false; + } /* The copyright message is a variable length string. */ if (bfd_write ((PTR) nlm_copyright_header (abfd) -> copyrightMessage, nlm_copyright_header (abfd) -> copyrightMessageLength + 1, @@ -897,6 +915,7 @@ DEFUN (nlm_get_symtab_upper_bound, (abfd), bfd * abfd) i_fxdhdrp = nlm_fixed_header (abfd); symcount = (i_fxdhdrp -> numberOfPublics + + i_fxdhdrp -> numberOfDebugRecords + i_fxdhdrp -> numberOfExternalReferences); symtab_size = (symcount + 1) * (sizeof (asymbol)); return (symtab_size); @@ -986,16 +1005,10 @@ nlm_print_symbol (abfd, afile, symbol, how) N bytes the symbol name 4 bytes the symbol offset from start of it's section - Note that we currently ignore the internal debug records. There is - a lot of duplication between the export records and the internal debug - records. We may in the future, want to merge the information from the - debug records with the information from the export records to produce - a more complete symbol table, treating additional information from the - debug records as static symbols. (FIXME) - - We do read in the import records. These are treated as undefined - symbols. As we read them in we also read in the associated reloc - information, which is attached to the symbol. + We also read in the debugging symbols and import records. Import + records are treated as undefined symbols. As we read the import + records we also read in the associated reloc information, which is + attached to the symbol. The bfd symbols are copied to SYMPTRS. @@ -1011,7 +1024,8 @@ nlm_slurp_symbol_table (abfd) bfd_size_type totsymcount; /* Number of NLM symbols */ bfd_size_type symcount; /* Counter of NLM symbols */ nlm_symbol_type *sym; /* Pointer to current bfd symbol */ - char symlength; /* Symbol length read into here */ + unsigned char symlength; /* Symbol length read into here */ + unsigned char symtype; /* Type of debugging symbol */ bfd_size_type rcount; /* Number of relocs */ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */ boolean (*read_reloc_func) PARAMS ((bfd *, nlm_symbol_type *, asection **, @@ -1031,6 +1045,7 @@ nlm_slurp_symbol_table (abfd) abfd -> symcount = 0; i_fxdhdrp = nlm_fixed_header (abfd); totsymcount = (i_fxdhdrp -> numberOfPublics + + i_fxdhdrp -> numberOfDebugRecords + i_fxdhdrp -> numberOfExternalReferences); if (totsymcount == 0) { @@ -1092,6 +1107,59 @@ nlm_slurp_symbol_table (abfd) sym++; } + /* Read the debugging records. */ + + if (i_fxdhdrp -> numberOfDebugRecords > 0) + { + if (bfd_seek (abfd, i_fxdhdrp -> debugInfoOffset, SEEK_SET) == -1) + { + bfd_error = system_call_error; + return (false); + } + + symcount += i_fxdhdrp -> numberOfDebugRecords; + while (abfd -> symcount < symcount) + { + if ((bfd_read ((PTR) &symtype, sizeof (symtype), 1, abfd) + != sizeof (symtype)) + || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp) + || (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) + != sizeof (symlength))) + { + bfd_error = system_call_error; + return false; + } + sym -> symbol.the_bfd = abfd; + sym -> symbol.name = bfd_alloc (abfd, symlength + 1); + if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd) + != symlength) + { + bfd_error = system_call_error; + return (false); + } + sym -> symbol.flags = BSF_LOCAL; + sym -> symbol.value = get_word (abfd, temp); + if (symtype == 0) + { + sym -> symbol.section = + bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); + } + else if (symtype == 1) + { + sym -> symbol.flags |= BSF_FUNCTION; + sym -> symbol.section = + bfd_get_section_by_name (abfd, NLM_CODE_NAME); + } + else + { + sym -> symbol.section = &bfd_abs_section; + } + sym -> rcnt = 0; + abfd -> symcount++; + sym++; + } + } + /* Read in the import records. We can only do this if we know how to read relocs for this target. */ @@ -1356,11 +1424,23 @@ nlm_compute_section_file_positions (abfd) bfd_vma text_low, data_low; int text_align, data_align, other_align; file_ptr text_ptr, data_ptr, other_ptr; + asection *bss_sec; asymbol **sym_ptr_ptr; if (abfd->output_has_begun == true) return true; + /* Make sure we have a section to hold uninitialized data. */ + bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); + if (bss_sec == NULL) + { + if (! add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, + (file_ptr) 0, (bfd_size_type) 0, + SEC_ALLOC)) + return false; + bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); + } + abfd->output_has_begun = true; /* The fixed header. */ @@ -1483,22 +1563,8 @@ nlm_compute_section_file_positions (abfd) if (sym_ptr_ptr != NULL) { asymbol **sym_end; - asection *bss_sec; bfd_vma add; - /* Make sure we have a section to hold uninitialized data. */ - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - if (bss_sec == NULL) - { - if (! add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, - (file_ptr) 0, (bfd_size_type) 0, - SEC_ALLOC)) - return false; - bss_sec = bfd_get_section_by_name (abfd, - NLM_UNINITIALIZED_DATA_NAME); - bss_sec->vma = data_low + data; - } - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); add = 0; for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) @@ -1553,9 +1619,8 @@ nlm_set_section_contents (abfd, section, location, offset, count) the relocs are already acceptable, this will not do anything. */ if (section->reloc_count != 0) { - boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR data, - bfd_vma offset, - bfd_size_type count)); + boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR, + bfd_vma, bfd_size_type)); mangle_relocs_func = nlm_mangle_relocs_func (abfd); if (mangle_relocs_func != NULL) @@ -1635,6 +1700,7 @@ nlm_write_object_contents (abfd) bfd_size_type external_reloc_count, internal_reloc_count, i, c; struct reloc_and_sec *external_relocs; asymbol **sym_ptr_ptr; + file_ptr last; if (abfd->output_has_begun == false && nlm_compute_section_file_positions (abfd) == false) @@ -1833,7 +1899,6 @@ nlm_write_object_contents (abfd) asymbol *sym; bfd_byte len; bfd_vma offset; - asection *sec; bfd_byte temp[NLM_TARGET_LONG_SIZE]; sym = *sym_ptr_ptr; @@ -1882,118 +1947,118 @@ nlm_write_object_contents (abfd) } nlm_fixed_header (abfd)->numberOfPublics = c; - nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd); - c = 0; - sym_ptr_ptr = bfd_get_outsymbols (abfd); - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); - for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) + /* Write out the debugging records. The NLM conversion program + wants to be able to inhibit this, so as a special hack if + debugInfoOffset is set to -1 we don't write any debugging + information. This can not be handled by fiddling with the + symbol table, because exported symbols appear in both the + exported symbol list and the debugging information. */ + if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) -1) { - asymbol *sym; - bfd_byte type, len; - bfd_vma offset; - asection *sec; - bfd_byte temp[NLM_TARGET_LONG_SIZE]; - - sym = *sym_ptr_ptr; - - /* The NLM notion of a debugging symbol is actually what BFD - calls a local or global symbol. What BFD calls a - debugging symbol NLM does not understand at all. */ - if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0 - || (sym->flags & BSF_DEBUGGING) != 0 - || bfd_get_section (sym) == &bfd_und_section) - continue; - - ++c; - - offset = bfd_asymbol_value (sym); - sec = sym->section; - if (sec->flags & SEC_CODE) - { - offset -= nlm_get_text_low (abfd); - type = 1; - } - else if (sec->flags & (SEC_DATA | SEC_ALLOC)) - { - offset -= nlm_get_data_low (abfd); - type = 0; - } - else - type = 2; - - /* The type is 0 for data, 1 for code, 2 for absolute. */ - if (bfd_write (&type, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - { - bfd_error = system_call_error; - return false; - } - - put_word (abfd, offset, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) + nlm_fixed_header (abfd)->debugInfoOffset = 0; + nlm_fixed_header (abfd)->numberOfDebugRecords = 0; + } + else + { + nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd); + c = 0; + sym_ptr_ptr = bfd_get_outsymbols (abfd); + sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); + for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) { - bfd_error = system_call_error; - return false; - } + asymbol *sym; + bfd_byte type, len; + bfd_vma offset; + bfd_byte temp[NLM_TARGET_LONG_SIZE]; + + sym = *sym_ptr_ptr; + + /* The NLM notion of a debugging symbol is actually what + BFD calls a local or global symbol. What BFD calls a + debugging symbol NLM does not understand at all. */ + if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0 + || (sym->flags & BSF_DEBUGGING) != 0 + || bfd_get_section (sym) == &bfd_und_section) + continue; + + ++c; + + offset = bfd_asymbol_value (sym); + sec = sym->section; + if (sec->flags & SEC_CODE) + { + offset -= nlm_get_text_low (abfd); + type = 1; + } + else if (sec->flags & (SEC_DATA | SEC_ALLOC)) + { + offset -= nlm_get_data_low (abfd); + type = 0; + } + else + type = 2; - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - { - bfd_error = system_call_error; - return false; - } + /* The type is 0 for data, 1 for code, 2 for absolute. */ + if (bfd_write (&type, sizeof (bfd_byte), 1, abfd) + != sizeof (bfd_byte)) + { + bfd_error = system_call_error; + return false; + } - /* Exported symbols may get an additional debugging record - without the prefix. */ - if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0) - { - char *s; + put_word (abfd, offset, temp); + if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) + { + bfd_error = system_call_error; + return false; + } - s = strchr (sym->name, '@'); - if (s != NULL) + len = strlen (sym->name); + if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) + != sizeof (bfd_byte)) + || bfd_write (sym->name, len, 1, abfd) != len) { - ++c; - - if ((bfd_write (&type, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - || (bfd_write (temp, sizeof (temp), 1, abfd) - != sizeof (temp))) - { - bfd_error = system_call_error; - return false; - } - - ++s; - - len = strlen (s); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - || bfd_write (s, len, 1, abfd) != len) - { - bfd_error = system_call_error; - return false; - } + bfd_error = system_call_error; + return false; } - } - } - nlm_fixed_header (abfd)->numberOfDebugRecords = c; + } + nlm_fixed_header (abfd)->numberOfDebugRecords = c; + } } + /* NLMLINK fills in offset values even if there is no data, so we do + the same. */ + last = bfd_tell (abfd); + if (nlm_fixed_header (abfd)->codeImageOffset == 0) + nlm_fixed_header (abfd)->codeImageOffset = last; + if (nlm_fixed_header (abfd)->dataImageOffset == 0) + nlm_fixed_header (abfd)->dataImageOffset = last; + if (nlm_fixed_header (abfd)->customDataOffset == 0) + nlm_fixed_header (abfd)->customDataOffset = last; + if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0) + nlm_fixed_header (abfd)->moduleDependencyOffset = last; + if (nlm_fixed_header (abfd)->relocationFixupOffset == 0) + nlm_fixed_header (abfd)->relocationFixupOffset = last; + if (nlm_fixed_header (abfd)->externalReferencesOffset == 0) + nlm_fixed_header (abfd)->externalReferencesOffset = last; + if (nlm_fixed_header (abfd)->publicsOffset == 0) + nlm_fixed_header (abfd)->publicsOffset = last; + if (nlm_fixed_header (abfd)->debugInfoOffset == 0) + nlm_fixed_header (abfd)->debugInfoOffset = last; + /* At this point everything has been written out except the fixed header. */ memcpy (nlm_fixed_header (abfd)->signature, NLM_SIGNATURE, NLM_SIGNATURE_SIZE); nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION; nlm_fixed_header (abfd)->codeStartOffset = - bfd_get_start_address (abfd) - nlm_get_text_low (abfd); + (bfd_get_start_address (abfd) + - nlm_get_text_low (abfd)); /* We have no convenient way for the caller to pass in the exit procedure or the check unload procedure, so the caller must set the values in the header to the values of the symbols. */ - if (nlm_fixed_header (abfd)->exitProcedureOffset != 0) - nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd); + nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd); if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0) nlm_fixed_header (abfd)->checkUnloadProcedureOffset -= nlm_get_text_low (abfd); -- 2.7.4