aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-04-21 16:13:01 +0000
committerIan Lance Taylor <ian@airs.com>1994-04-21 16:13:01 +0000
commit6c534df0c9f1b653b392984d1757c2732492ba34 (patch)
treea23c27ab83dfc9e9870d9f6940a4dd4327a74dc9
parent1f573a795dfcc69b66a3a1542b56ca99fd4816e7 (diff)
downloadgdb-6c534df0c9f1b653b392984d1757c2732492ba34.zip
gdb-6c534df0c9f1b653b392984d1757c2732492ba34.tar.gz
gdb-6c534df0c9f1b653b392984d1757c2732492ba34.tar.bz2
* 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.
-rw-r--r--bfd/ChangeLog14
-rw-r--r--bfd/libnlm.h2
-rw-r--r--bfd/nlmcode.h159
3 files changed, 155 insertions, 20 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 51c9156..c69b2c0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/libnlm.h b/bfd/libnlm.h
index cf6885d..acdfcdf 100644
--- a/bfd/libnlm.h
+++ b/bfd/libnlm.h
@@ -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))
diff --git a/bfd/nlmcode.h b/bfd/nlmcode.h
index 61e748f..6655a6f 100644
--- a/bfd/nlmcode.h
+++ b/bfd/nlmcode.h
@@ -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 fixed length header. */
+ /* 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;
+ }
- 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))
+ /* 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 (!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