coff: Handle massive relocations
The backport of4db724fdd7
359b63f897
01102ee8e6
2672af7379
so coff output target to be able to handle massive relocations. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
This commit is contained in:
parent
3cb0e8c052
commit
cb9a459560
2 changed files with 44 additions and 3 deletions
|
@ -837,6 +837,25 @@ static int coff_directives(enum directives directive, char *value, int pass)
|
|||
}
|
||||
}
|
||||
|
||||
/* handle relocations storm, valid for win32/64 only */
|
||||
static inline void coff_adjust_relocs(struct Section *s)
|
||||
{
|
||||
if (s->nrelocs < IMAGE_SCN_MAX_RELOC)
|
||||
return;
|
||||
#ifdef OF_COFF
|
||||
else
|
||||
{
|
||||
if (ofmt == &of_coff)
|
||||
nasm_error(ERR_FATAL,
|
||||
"Too many relocations (%d) for section `%s'",
|
||||
s->nrelocs, s->name);
|
||||
}
|
||||
#endif
|
||||
|
||||
s->flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
|
||||
s->nrelocs++;
|
||||
}
|
||||
|
||||
static void coff_write(void)
|
||||
{
|
||||
int32_t pos, sympos, vsize;
|
||||
|
@ -860,13 +879,15 @@ static void coff_write(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Work out how big the file will get. Calculate the start of
|
||||
* the `real' symbols at the same time.
|
||||
* Work out how big the file will get.
|
||||
* Calculate the start of the `real' symbols at the same time.
|
||||
* Check for massive relocations.
|
||||
*/
|
||||
pos = 0x14 + 0x28 * nsects;
|
||||
initsym = 3; /* two for the file, one absolute */
|
||||
for (i = 0; i < nsects; i++) {
|
||||
if (sects[i]->data) {
|
||||
coff_adjust_relocs(sects[i]);
|
||||
sects[i]->pos = pos;
|
||||
pos += sects[i]->len;
|
||||
sects[i]->relpos = pos;
|
||||
|
@ -939,7 +960,18 @@ static void coff_section_header(char *name, int32_t vsize,
|
|||
fwriteint32_t(datapos, ofile);
|
||||
fwriteint32_t(relpos, ofile);
|
||||
fwriteint32_t(0L, ofile); /* no line numbers - we don't do 'em */
|
||||
fwriteint16_t(nrelocs, ofile);
|
||||
|
||||
/*
|
||||
* a special case -- if there are too many relocs
|
||||
* we have to put IMAGE_SCN_MAX_RELOC here and write
|
||||
* the real relocs number into VirtualAddress of first
|
||||
* relocation
|
||||
*/
|
||||
if (flags & IMAGE_SCN_LNK_NRELOC_OVFL)
|
||||
fwriteint16_t(IMAGE_SCN_MAX_RELOC, ofile);
|
||||
else
|
||||
fwriteint16_t(nrelocs, ofile);
|
||||
|
||||
fwriteint16_t(0, ofile); /* again, no line numbers */
|
||||
fwriteint32_t(flags, ofile);
|
||||
}
|
||||
|
@ -948,6 +980,13 @@ static void coff_write_relocs(struct Section *s)
|
|||
{
|
||||
struct Reloc *r;
|
||||
|
||||
/* a real number of relocations if needed */
|
||||
if (s->flags & IMAGE_SCN_LNK_NRELOC_OVFL) {
|
||||
fwriteint32_t(s->nrelocs, ofile);
|
||||
fwriteint32_t(0, ofile);
|
||||
fwriteint16_t(0, ofile);
|
||||
}
|
||||
|
||||
for (r = s->head; r; r = r->next) {
|
||||
fwriteint32_t(r->address, ofile);
|
||||
fwriteint32_t(r->symbol + (r->symbase == REAL_SYMBOLS ? initsym :
|
||||
|
|
|
@ -137,6 +137,8 @@
|
|||
#define IMAGE_SCN_LNK_REMOVE 0x00000800
|
||||
#define IMAGE_SCN_LNK_COMDAT 0x00001000
|
||||
|
||||
#define IMAGE_SCN_MAX_RELOC 0xffff
|
||||
|
||||
#define IMAGE_SCN_MEM_FARDATA 0x00008000
|
||||
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
|
||||
#define IMAGE_SCN_MEM_16BIT 0x00020000
|
||||
|
|
Loading…
Reference in a new issue