107 lines
4.0 KiB
Plaintext
107 lines
4.0 KiB
Plaintext
$OpenBSD: patch-bfd_coffgen_c,v 1.1 2008/10/01 04:46:19 ckuethe Exp $
|
|
--- bfd/coffgen.c.orig Sun Aug 12 18:43:34 2007
|
|
+++ bfd/coffgen.c Sat Sep 27 20:20:27 2008
|
|
@@ -687,6 +687,20 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
|
|
if (last_file != NULL)
|
|
last_file->n_value = native_index;
|
|
last_file = &(s->u.syment);
|
|
+ if (bfd_get_arch (bfd_ptr) == bfd_arch_avr
|
|
+ && bfd_coff_long_filenames (bfd_ptr)
|
|
+ && s->u.syment.n_numaux > 0)
|
|
+ {
|
|
+ /* AVR COFF records long filenames in successive aux
|
|
+ records. Adjust the number of aux records
|
|
+ required here, so the renumbering will account
|
|
+ for them. */
|
|
+ unsigned int filnmlen = bfd_coff_filnmlen (bfd_ptr);
|
|
+ unsigned int namelen = strlen (coff_symbol_ptr->symbol.name);
|
|
+ unsigned int n = (namelen + filnmlen - 1) / filnmlen;
|
|
+
|
|
+ s->u.syment.n_numaux = n > NAUXENTS? NAUXENTS: n;
|
|
+ }
|
|
}
|
|
else
|
|
/* Modify the symbol values according to their section and
|
|
@@ -815,6 +829,20 @@ coff_fix_symbol_name (bfd *abfd,
|
|
{
|
|
if (name_length <= filnmlen)
|
|
strncpy (auxent->x_file.x_fname, name, filnmlen);
|
|
+ else if (bfd_get_arch (abfd) == bfd_arch_avr)
|
|
+ {
|
|
+ /* AVR COFF records long filenames in successive aux records. */
|
|
+ int i = 1;
|
|
+ while (name_length > filnmlen && i < NAUXENTS)
|
|
+ {
|
|
+ strncpy (auxent->x_file.x_fname, name, filnmlen);
|
|
+ name += filnmlen;
|
|
+ name_length -= filnmlen;
|
|
+ i++;
|
|
+ auxent = &(native + i)->u.auxent;
|
|
+ }
|
|
+ strncpy (auxent->x_file.x_fname, name, filnmlen);
|
|
+ }
|
|
else
|
|
{
|
|
auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
|
|
@@ -1218,7 +1246,11 @@ coff_write_symbols (bfd *abfd)
|
|
if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
|
|
return FALSE;
|
|
}
|
|
- maxlen = bfd_coff_filnmlen (abfd);
|
|
+ if (bfd_get_arch (abfd) == bfd_arch_avr)
|
|
+ /* AVR COFF handles long file names in aux records. */
|
|
+ maxlen = name_length;
|
|
+ else
|
|
+ maxlen = bfd_coff_filnmlen (abfd);
|
|
}
|
|
else
|
|
maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
|
|
@@ -1655,14 +1687,27 @@ coff_get_normalized_symtab (bfd *abfd)
|
|
{
|
|
/* Ordinary short filename, put into memory anyway. The
|
|
Microsoft PE tools sometimes store a filename in
|
|
- multiple AUX entries. */
|
|
+ multiple AUX entries.
|
|
+ AVR COFF does it that way, too. */
|
|
if (internal_ptr->u.syment.n_numaux > 1
|
|
- && coff_data (abfd)->pe)
|
|
- internal_ptr->u.syment._n._n_n._n_offset =
|
|
- ((bfd_hostptr_t)
|
|
- copy_name (abfd,
|
|
- (internal_ptr + 1)->u.auxent.x_file.x_fname,
|
|
- internal_ptr->u.syment.n_numaux * symesz));
|
|
+ && (coff_data (abfd)->pe
|
|
+ || (bfd_get_arch (abfd) == bfd_arch_avr)))
|
|
+ {
|
|
+ char *b;
|
|
+ unsigned int i;
|
|
+
|
|
+ /* We allocate enough storage to fit the contents of
|
|
+ this many aux records, and simply append a \0.
|
|
+ This ensures the string will always be
|
|
+ terminated, even in the case where it just fit
|
|
+ into the aux records. */
|
|
+ b = (char *) bfd_alloc (abfd,
|
|
+ internal_ptr->u.syment.n_numaux * FILNMLEN + 1);
|
|
+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) b;
|
|
+ b[internal_ptr->u.syment.n_numaux * FILNMLEN] = '\0';
|
|
+ for (i = 0; i < internal_ptr->u.syment.n_numaux; i++, b += FILNMLEN)
|
|
+ memcpy (b, (internal_ptr + i + 1)->u.auxent.x_file.x_fname, FILNMLEN);
|
|
+ }
|
|
else
|
|
internal_ptr->u.syment._n._n_n._n_offset =
|
|
((bfd_hostptr_t)
|
|
@@ -1768,9 +1813,9 @@ coff_bfd_make_debug_symbol (bfd *abfd,
|
|
|
|
if (new == NULL)
|
|
return NULL;
|
|
- /* @@ The 10 is a guess at a plausible maximum number of aux entries
|
|
- (but shouldn't be a constant). */
|
|
- amt = sizeof (combined_entry_type) * 10;
|
|
+ /* @@ The NAUXENTS is a guess at a plausible maximum number of aux
|
|
+ entries (but shouldn't be a constant). */
|
|
+ amt = sizeof (combined_entry_type) * (NAUXENTS + 1);
|
|
new->native = bfd_zalloc (abfd, amt);
|
|
if (!new->native)
|
|
return NULL;
|