* 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.
This commit is contained in:
Ian Lance Taylor 1993-08-31 17:28:03 +00:00
parent aef3ae9a8f
commit 45a78ebbfb
2 changed files with 219 additions and 139 deletions

View file

@ -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.

View file

@ -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)
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++)
{
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;
asymbol *sym;
bfd_byte type, len;
bfd_vma offset;
bfd_byte temp[NLM_TARGET_LONG_SIZE];
/* 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;
}
sym = *sym_ptr_ptr;
put_word (abfd, offset, temp);
if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
{
bfd_error = system_call_error;
return false;
}
/* 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;
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;
}
++c;
/* Exported symbols may get an additional debugging record
without the prefix. */
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
{
char *s;
s = strchr (sym->name, '@');
if (s != NULL)
offset = bfd_asymbol_value (sym);
sec = sym->section;
if (sec->flags & SEC_CODE)
{
++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;
}
offset -= nlm_get_text_low (abfd);
type = 1;
}
}
}
nlm_fixed_header (abfd)->numberOfDebugRecords = c;
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))
{
bfd_error = system_call_error;
return false;
}
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;
}
}
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);