Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

djgpp patches #3

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
134 changes: 134 additions & 0 deletions bfd/coff-go32.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define TARGET_SYM i386_coff_go32_vec
#define TARGET_NAME "coff-go32"
#define TARGET_UNDERSCORE '_'
#define COFF_GO32
#define COFF_LONG_SECTION_NAMES
#define COFF_SUPPORT_GNU_LINKONCE
#define COFF_LONG_FILENAMES
Expand All @@ -42,4 +43,137 @@
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }

/* Section contains extended relocations. */
#define IMAGE_SCN_LNK_NRELOC_OVFL (0x01000000)

#include "sysdep.h"
#include "bfd.h"

/* The following functions are not static, because they are also
used for coff-go32-exe (coff-stgo32.c). */
bfd_boolean _bfd_go32_mkobject (bfd *);
void _bfd_go32_swap_scnhdr_in (bfd *, void *, void *);
unsigned int _bfd_go32_swap_scnhdr_out (bfd *, void *, void *);

#define coff_mkobject _bfd_go32_mkobject
#define coff_swap_scnhdr_in _bfd_go32_swap_scnhdr_in
#define coff_swap_scnhdr_out _bfd_go32_swap_scnhdr_out

#include "coff-i386.c"

bfd_boolean
_bfd_go32_mkobject (bfd * abfd)
{
const bfd_size_type amt = sizeof (coff_data_type);

abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
if (abfd->tdata.coff_obj_data == NULL)
return FALSE;

coff_data (abfd)->go32 = TRUE;

return TRUE;
}

void
_bfd_go32_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
{
SCNHDR *scnhdr_ext = (SCNHDR *) ext;
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;

memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));

scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);

scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);

/* DJGPP follows the same strategy as PE COFF.
Iff the file is an executable then the higher 16 bits
of the line number have been stored in the relocation
counter field. */
if (abfd->flags & EXEC_P && (strcmp (scnhdr_ext->s_name, ".text") == 0))
{
scnhdr_int->s_nlnno
= (GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc) << 16)
+ GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
scnhdr_int->s_nreloc = 0;
}
}

unsigned int
_bfd_go32_swap_scnhdr_out (bfd * abfd, void * in, void * out)
{
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
SCNHDR *scnhdr_ext = (SCNHDR *) out;
unsigned int ret = bfd_coff_scnhsz (abfd);

memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));

PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);

if (abfd->flags & EXEC_P && (strcmp (scnhdr_int->s_name, ".text") == 0))
{
/* DJGPP follows the same strategy as PE COFF.
By inference from looking at MS output, the 32 bit field
which is the combination of the number_of_relocs and
number_of_linenos is used for the line number count in
executables. A 16-bit field won't do for cc1. The MS
document says that the number of relocs is zero for
executables, but the 17-th bit has been observed to be there.
Overflow is not an issue: a 4G-line program will overflow a
bunch of other fields long before this! */
PUT_SCNHDR_NLNNO (abfd, (scnhdr_int->s_nlnno & 0xffff),
scnhdr_ext->s_nlnno);
PUT_SCNHDR_NRELOC (abfd, (scnhdr_int->s_nlnno >> 16),
scnhdr_ext->s_nreloc);
}
else
{
/* DJGPP follows the same strategy as PE COFF. */
if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
else
{
char buf[sizeof (scnhdr_int->s_name) + 1];

memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
buf[sizeof (scnhdr_int->s_name)] = '\0';
_bfd_error_handler
/* xgettext:c-format */
(_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"),
abfd, buf, scnhdr_int->s_nlnno);
bfd_set_error (bfd_error_file_truncated);
PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
ret = 0;
}

/* Although we could encode 0xffff relocs here, we do not, to be
consistent with other parts of bfd. Also it lets us warn, as
we should never see 0xffff here w/o having the overflow flag
set. */
if (scnhdr_int->s_nreloc < MAX_SCNHDR_NRELOC)
PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
else
{
/* DJGPP can deal with large #s of relocs, but not here. */
PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
}
}

return ret;
}
30 changes: 14 additions & 16 deletions bfd/coff-stgo32.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }

/* Section contains extended relocations. */
#define IMAGE_SCN_LNK_NRELOC_OVFL (0x01000000)

#include "sysdep.h"
#include "bfd.h"
#include "coff/msdos.h"
Expand All @@ -55,10 +58,17 @@ static bfd_boolean go32exe_write_object_contents (bfd *);
static bfd_boolean go32exe_mkobject (bfd *);
static bfd_boolean go32exe_copy_private_bfd_data (bfd *, bfd *);

/* Defined in coff-go32.c. */
bfd_boolean _bfd_go32_mkobject (bfd *);
void _bfd_go32_swap_scnhdr_in (bfd *, void *, void *);
unsigned int _bfd_go32_swap_scnhdr_out (bfd *, void *, void *);

#define COFF_CHECK_FORMAT go32exe_check_format
#define COFF_WRITE_CONTENTS go32exe_write_object_contents
#define coff_mkobject go32exe_mkobject
#define coff_bfd_copy_private_bfd_data go32exe_copy_private_bfd_data
#define coff_swap_scnhdr_in _bfd_go32_swap_scnhdr_in
#define coff_swap_scnhdr_out _bfd_go32_swap_scnhdr_out

#include "coff-i386.c"

Expand Down Expand Up @@ -352,32 +362,20 @@ go32exe_write_object_contents (bfd *abfd)
static bfd_boolean
go32exe_mkobject (bfd *abfd)
{
coff_data_type *coff = NULL;
const bfd_size_type amt = sizeof (coff_data_type);

/* Don't output to an archive. */
if (abfd->my_archive != NULL)
return FALSE;

abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
if (abfd->tdata.coff_obj_data == NULL)
if (!_bfd_go32_mkobject (abfd))
return FALSE;
coff = coff_data (abfd);
coff->symbols = NULL;
coff->conversion_table = NULL;
coff->raw_syments = NULL;
coff->relocbase = 0;
coff->local_toc_sym_map = 0;

go32exe_create_stub (abfd);
if (coff->stub == NULL)
if (coff_data (abfd)->stub == NULL)
{
bfd_release (abfd, coff);
bfd_release (abfd, coff_data (abfd));
return FALSE;
}
abfd->origin = coff->stub_size;

/* make_abs_section(abfd);*/ /* ??? */
abfd->origin = coff_data (abfd)->stub_size;

return TRUE;
}
64 changes: 58 additions & 6 deletions bfd/coffcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,10 @@ CODE_FRAGMENT
#define GNU_LINKONCE_WT ".gnu.linkonce.wt."
#define DOT_RELOC ".reloc"

#if defined(COFF_WITH_PE) || defined(COFF_GO32_EXE) || defined(COFF_GO32)
# define COFF_WITH_EXTENDED_RELOC_COUNTER
#endif

#if defined (COFF_LONG_SECTION_NAMES)
/* Needed to expand the inputs to BLANKOR1TOODD. */
#define COFFLONGSECTIONCATHELPER(x,y) x ## y
Expand Down Expand Up @@ -1964,6 +1968,39 @@ coff_set_alignment_hook (bfd *abfd, asection *section, void * scnhdr)
}

#else /* ! RS6000COFF_C */
#if defined (COFF_GO32_EXE) || defined (COFF_GO32)

static void
coff_set_alignment_hook (bfd * abfd, asection * section, void * scnhdr)
{
struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;

/* Check for extended relocs. */
if (hdr->s_flags & IMAGE_SCN_LNK_NRELOC_OVFL)
{
struct external_reloc dst;
struct internal_reloc n;
const file_ptr oldpos = bfd_tell (abfd);
const bfd_size_type relsz = bfd_coff_relsz (abfd);

if (bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0) != 0)
return;
if (bfd_bread (& dst, relsz, abfd) != relsz)
return;

coff_swap_reloc_in (abfd, &dst, &n);
if (bfd_seek (abfd, oldpos, 0) != 0)
return;
section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;
section->rel_filepos += relsz;
}
else if (hdr->s_nreloc == 0xffff)
_bfd_error_handler
(_("%pB: warning: claims to have 0xffff relocs, without overflow"),
abfd);
}

#else /* ! COFF_GO32_EXE && ! COFF_GO32 */

static void
coff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
Expand All @@ -1972,6 +2009,7 @@ coff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
{
}

#endif /* ! COFF_GO32_EXE && ! COFF_GO32 */
#endif /* ! RS6000COFF_C */
#endif /* ! COFF_WITH_PE */
#endif /* ! COFF_ALIGN_IN_SECTION_HEADER */
Expand Down Expand Up @@ -2521,8 +2559,8 @@ coff_write_relocs (bfd * abfd, int first_undef)
if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0)
return FALSE;

#ifdef COFF_WITH_PE
if (obj_pe (abfd) && s->reloc_count >= 0xffff)
#ifdef COFF_WITH_EXTENDED_RELOC_COUNTER
if ((obj_pe (abfd) || obj_go32 (abfd)) && s->reloc_count >= 0xffff)
{
/* Encode real count here as first reloc. */
struct internal_reloc n;
Expand Down Expand Up @@ -3382,9 +3420,9 @@ coff_write_object_contents (bfd * abfd)
for (current = abfd->sections; current != NULL; current =
current->next)
{
#ifdef COFF_WITH_PE
#ifdef COFF_WITH_EXTENDED_RELOC_COUNTER
/* We store the actual reloc count in the first reloc's addr. */
if (obj_pe (abfd) && current->reloc_count >= 0xffff)
if ((obj_pe (abfd) || obj_go32 (abfd)) && current->reloc_count >= 0xffff)
reloc_count ++;
#endif
reloc_count += current->reloc_count;
Expand Down Expand Up @@ -3412,9 +3450,9 @@ coff_write_object_contents (bfd * abfd)
{
current->rel_filepos = reloc_base;
reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
#ifdef COFF_WITH_PE
#ifdef COFF_WITH_EXTENDED_RELOC_COUNTER
/* Extra reloc to hold real count. */
if (obj_pe (abfd) && current->reloc_count >= 0xffff)
if ((obj_pe (abfd) || obj_go32 (abfd)) && current->reloc_count >= 0xffff)
reloc_base += bfd_coff_relsz (abfd);
#endif
}
Expand Down Expand Up @@ -3749,6 +3787,20 @@ coff_write_object_contents (bfd * abfd)
#endif
#endif

#if defined (COFF_GO32_EXE) || defined (COFF_GO32)
/* Pad section headers. */
if ((abfd->flags & EXEC_P) && abfd->sections != NULL)
{
file_ptr cur_ptr = scn_base
+ abfd->section_count * bfd_coff_scnhsz (abfd);
long fill_size = (abfd->sections->filepos - cur_ptr);
bfd_byte *b = bfd_zmalloc (fill_size);
if (b)
bfd_bwrite ((PTR)b, fill_size, abfd);
free (b);
}
#endif

/* OK, now set up the filehdr... */

/* Don't include the internal abs section in the section count */
Expand Down
4 changes: 2 additions & 2 deletions bfd/cofflink.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ _bfd_coff_final_link (bfd *abfd,
rel_filepos += o->reloc_count * relsz;
/* In PE COFF, if there are at least 0xffff relocations an
extra relocation will be written out to encode the count. */
if (obj_pe (abfd) && o->reloc_count >= 0xffff)
if ((obj_pe (abfd) || obj_go32 (abfd)) && o->reloc_count >= 0xffff)
rel_filepos += relsz;
}

Expand Down Expand Up @@ -1108,7 +1108,7 @@ _bfd_coff_final_link (bfd *abfd,

if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
goto error_return;
if (obj_pe (abfd) && o->reloc_count >= 0xffff)
if ((obj_pe (abfd) || obj_go32 (abfd)) && o->reloc_count >= 0xffff)
{
/* In PE COFF, write the count of relocs as the first
reloc. The header overflow bit will be set
Expand Down
4 changes: 4 additions & 0 deletions bfd/coffswap.h
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
return AOUTSZ;
}

#ifndef coff_swap_scnhdr_in
static void
coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
{
Expand All @@ -750,7 +751,9 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
#endif
}
#endif

#ifndef coff_swap_scnhdr_out
static unsigned int
coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
{
Expand Down Expand Up @@ -806,3 +809,4 @@ coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
#endif
return ret;
}
#endif
6 changes: 5 additions & 1 deletion bfd/libcoff-in.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ extern "C" {

#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
#define obj_pe(bfd) (coff_data (bfd)->pe)
#define obj_go32(bfd) (coff_data (bfd)->go32)
#define obj_symbols(bfd) (coff_data (bfd)->symbols)
#define obj_sym_filepos(bfd) (coff_data (bfd)->sym_filepos)
#define obj_sym_filepos(bfd) (coff_data (bfd)->sym_filepos)
#define obj_relocbase(bfd) (coff_data (bfd)->relocbase)
#define obj_raw_syments(bfd) (coff_data (bfd)->raw_syments)
#define obj_raw_syment_count(bfd) (coff_data (bfd)->raw_syment_count)
Expand Down Expand Up @@ -114,6 +115,9 @@ typedef struct coff_tdata
used by ARM code. */
flagword flags;

/* Is this a GO32 coff file? */
bfd_boolean go32;

/* A stub (extra data prepended before the COFF image) and its size.
Used by coff-go32-exe, it contains executable data that loads the
COFF object into memory. */
Expand Down