* libnlm.h (struct nlm_obj_tdata): Add nlm_cygnus_section_hdr

field.
	(nlm_cygnus_section_header): New accessor macro.
	* nlmcode.h (nlm_object_p): Free new tdata structure if failure.
	Add fixed sections before swapping in auxiliary headers.  After
	adding sections, treat errors as real, not as wrong format.
	(nlm_swap_auxiliary_headers_in): Swap in the sections header; add
	sections to the BFD for each section it describes.
	(nlm_swap_auxiliary_headers_out): Swap out the sections header.
	(nlm_compute_section_file_positions): Account for the size of the
	sections header.
This commit is contained in:
Ian Lance Taylor 1994-04-21 16:13:01 +00:00
parent 1f573a795d
commit 6c534df0c9
3 changed files with 154 additions and 19 deletions

View File

@ -1,3 +1,17 @@
Thu Apr 21 11:58:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* libnlm.h (struct nlm_obj_tdata): Add nlm_cygnus_section_hdr
field.
(nlm_cygnus_section_header): New accessor macro.
* nlmcode.h (nlm_object_p): Free new tdata structure if failure.
Add fixed sections before swapping in auxiliary headers. After
adding sections, treat errors as real, not as wrong format.
(nlm_swap_auxiliary_headers_in): Swap in the sections header; add
sections to the BFD for each section it describes.
(nlm_swap_auxiliary_headers_out): Swap out the sections header.
(nlm_compute_section_file_positions): Account for the size of the
sections header.
Wed Apr 20 16:45:51 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
* coff-sparc.c (sparccoff_vec): Change minimum alignment power to

View File

@ -91,6 +91,7 @@ struct nlm_obj_tdata
Nlm_Internal_Copyright_Header nlm_copyright_hdr[1];
Nlm_Internal_Extended_Header nlm_extended_hdr[1];
Nlm_Internal_Custom_Header nlm_custom_hdr[1];
Nlm_Internal_Cygnus_Section_Header nlm_cygnus_section_hdr[1];
/* BFD NLM symbols. */
nlmNAME(symbol_type) *nlm_symbols;
/* Lowest text and data VMA values. */
@ -122,6 +123,7 @@ struct nlm_obj_tdata
#define nlm_copyright_header(bfd) (nlm_tdata(bfd) -> nlm_copyright_hdr)
#define nlm_extended_header(bfd) (nlm_tdata(bfd) -> nlm_extended_hdr)
#define nlm_custom_header(bfd) (nlm_tdata(bfd) -> nlm_custom_hdr)
#define nlm_cygnus_section_header(bfd) (nlm_tdata(bfd)->nlm_cygnus_section_hdr)
#define nlm_get_symbols(bfd) (nlm_tdata(bfd) -> nlm_symbols)
#define nlm_set_symbols(bfd, p) (nlm_tdata(bfd) -> nlm_symbols = (p))
#define nlm_set_text_low(bfd, i) (nlm_tdata(bfd) -> nlm_text_low = (i))

View File

@ -38,6 +38,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define Nlm_External_Copyright_Header NlmNAME(External_Copyright_Header)
#define Nlm_External_Extended_Header NlmNAME(External_Extended_Header)
#define Nlm_External_Custom_Header NlmNAME(External_Custom_Header)
#define Nlm_External_Cygnus_Section_Header \
NlmNAME(External_Cygnus_Section_Header)
#define nlm_symbol_type nlmNAME(symbol_type)
#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
@ -98,6 +100,7 @@ nlm_object_p (abfd)
boolean (*backend_object_p) PARAMS ((bfd *));
PTR x_fxdhdr = NULL;
Nlm_Internal_Fixed_Header *i_fxdhdrp;
struct nlm_obj_tdata *new_tdata = NULL;
const char *signature;
enum bfd_architecture arch;
@ -131,16 +134,20 @@ nlm_object_p (abfd)
/* Allocate an instance of the nlm_obj_tdata structure and hook it up to
the tdata pointer in the bfd. */
nlm_tdata (abfd) = (struct nlm_obj_tdata *)
bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
if (nlm_tdata (abfd) == NULL)
new_tdata = ((struct nlm_obj_tdata *)
bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)));
if (new_tdata == NULL)
{
bfd_set_error (bfd_error_no_memory);
goto got_no_match;
}
nlm_tdata (abfd) = new_tdata;
i_fxdhdrp = nlm_fixed_header (abfd);
nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
free (x_fxdhdr);
x_fxdhdr = NULL;
/* Check to see if we have an NLM file for this backend by matching
the NLM signature. */
@ -162,29 +169,39 @@ nlm_object_p (abfd)
/* There's no supported way to check for 32 bit versus 64 bit addresses,
so ignore this distinction for now. (FIXME) */
/* 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 required header. */
if (!nlm_swap_variable_header_in (abfd))
{
if (bfd_get_error () != bfd_error_system_call)
goto got_wrong_format_error;
else
goto got_no_match;
}
/* Swap in the rest of the fixed length header. */
/* Add the sections supplied by all NLM's, and then read in the
auxiliary headers. Reading the auxiliary headers may create
additional sections described in the cygnus_sections header.
From this point on we assume that we have an NLM, and do not
treat errors as indicating the wrong format. */
if (!nlm_swap_variable_header_in (abfd)
|| !nlm_swap_auxiliary_headers_in (abfd)
|| !add_bfd_section (abfd, NLM_CODE_NAME,
i_fxdhdrp->codeImageOffset,
i_fxdhdrp->codeImageSize,
(SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_RELOC))
if (!add_bfd_section (abfd, NLM_CODE_NAME,
i_fxdhdrp->codeImageOffset,
i_fxdhdrp->codeImageSize,
(SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_RELOC))
|| !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
i_fxdhdrp->dataImageOffset,
i_fxdhdrp->dataImageSize,
(SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_RELOC))
(SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_RELOC))
|| !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
(file_ptr) 0,
i_fxdhdrp->uninitializedDataSize,
SEC_ALLOC))
goto got_wrong_format_error;
goto got_no_match;
if (!nlm_swap_auxiliary_headers_in (abfd))
goto got_no_match;
if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
|| nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
@ -198,14 +215,14 @@ nlm_object_p (abfd)
if (arch != bfd_arch_unknown)
bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
if (x_fxdhdr != NULL)
free (x_fxdhdr);
return (abfd->xvec);
got_wrong_format_error:
bfd_set_error (bfd_error_wrong_format);
got_no_match:
nlm_tdata (abfd) = preserved_tdata;
if (new_tdata != NULL)
bfd_release (abfd, new_tdata);
if (x_fxdhdr != NULL)
free (x_fxdhdr);
return (NULL);
@ -524,6 +541,90 @@ nlm_swap_auxiliary_headers_in (abfd)
nlm_copyright_header (abfd)->copyrightMessageLength + 1)
return (false);
}
else if (strncmp (tempstr, "CyGnUsSeCs", 10) == 0)
{
Nlm_External_Cygnus_Section_Header thdr;
bfd_size_type len;
file_ptr pos;
bfd_byte *contents;
bfd_byte *p, *pend;
if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
return false;
memcpy (nlm_cygnus_section_header (abfd)->stamp, thdr.stamp,
sizeof (thdr.stamp));
nlm_cygnus_section_header (abfd)->offset =
get_word (abfd, (bfd_byte *) thdr.offset);
len = get_word (abfd, (bfd_byte *) thdr.length);
nlm_cygnus_section_header (abfd)->length = len;
/* This data this header points to provides a list of the
sections which were in the original object file which was
converted to become an NLM. We locate those sections and
add them to the BFD. Note that this is likely to create
a second .text, .data and .bss section; retrieving the
sections by name will get the actual NLM sections, which
is what we want to happen. The sections from the
original file, which may be subsets of the NLM section,
can only be found using bfd_map_over_sections. */
contents = (bfd_byte *) malloc (len);
if (contents == (bfd_byte *) NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
pos = bfd_tell (abfd);
if (bfd_seek (abfd, nlm_cygnus_section_header (abfd)->offset,
SEEK_SET) != 0
|| bfd_read (contents, len, 1, abfd) != len)
{
free (contents);
return false;
}
p = contents;
pend = p + len;
while (p < pend)
{
char *name;
size_t l;
file_ptr filepos;
bfd_size_type size;
asection *newsec;
/* The format of this information is
null terminated section name
zeroes to adjust to 4 byte boundary
4 byte section data file pointer
4 byte section size
*/
name = p;
l = strlen (name) + 1;
l = (l + 3) &~ 3;
p += l;
filepos = bfd_h_get_32 (abfd, p);
p += 4;
size = bfd_h_get_32 (abfd, p);
p += 4;
newsec = bfd_make_section_anyway (abfd, name);
if (newsec == (asection *) NULL)
{
free (contents);
return false;
}
newsec->_raw_size = size;
if (filepos != 0)
{
newsec->filepos = filepos;
newsec->flags |= SEC_HAS_CONTENTS;
}
}
free (contents);
if (bfd_seek (abfd, pos, SEEK_SET) != 0)
return false;
}
else
{
break;
@ -719,6 +820,21 @@ nlm_swap_auxiliary_headers_out (abfd)
return false;
}
/* Write out the Cygnus debugging header if there is one. */
if (find_nonzero ((PTR) nlm_cygnus_section_header (abfd),
sizeof (Nlm_Internal_Cygnus_Section_Header)))
{
Nlm_External_Cygnus_Section_Header thdr;
memcpy (thdr.stamp, "CyGnUsSeCs", 10);
put_word (abfd, (bfd_vma) nlm_cygnus_section_header (abfd)->offset,
(bfd_byte *) thdr.offset);
put_word (abfd, (bfd_vma) nlm_cygnus_section_header (abfd)->length,
(bfd_byte *) thdr.length);
if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
return false;
}
return true;
}
@ -1259,6 +1375,9 @@ nlm_compute_section_file_positions (abfd)
sizeof (Nlm_Internal_Copyright_Header)))
sofar += (sizeof (Nlm_External_Copyright_Header)
+ nlm_copyright_header (abfd)->copyrightMessageLength + 1);
if (find_nonzero ((PTR) nlm_cygnus_section_header (abfd),
sizeof (Nlm_Internal_Cygnus_Section_Header)))
sofar += sizeof (Nlm_External_Cygnus_Section_Header);
/* Compute the section file positions in two passes. First get the
sizes of the text and data sections, and then set the file