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)
|
static void coff_write(void)
|
||||||
{
|
{
|
||||||
int32_t pos, sympos, vsize;
|
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
|
* Work out how big the file will get.
|
||||||
* the `real' symbols at the same time.
|
* Calculate the start of the `real' symbols at the same time.
|
||||||
|
* Check for massive relocations.
|
||||||
*/
|
*/
|
||||||
pos = 0x14 + 0x28 * nsects;
|
pos = 0x14 + 0x28 * nsects;
|
||||||
initsym = 3; /* two for the file, one absolute */
|
initsym = 3; /* two for the file, one absolute */
|
||||||
for (i = 0; i < nsects; i++) {
|
for (i = 0; i < nsects; i++) {
|
||||||
if (sects[i]->data) {
|
if (sects[i]->data) {
|
||||||
|
coff_adjust_relocs(sects[i]);
|
||||||
sects[i]->pos = pos;
|
sects[i]->pos = pos;
|
||||||
pos += sects[i]->len;
|
pos += sects[i]->len;
|
||||||
sects[i]->relpos = pos;
|
sects[i]->relpos = pos;
|
||||||
|
@ -939,7 +960,18 @@ static void coff_section_header(char *name, int32_t vsize,
|
||||||
fwriteint32_t(datapos, ofile);
|
fwriteint32_t(datapos, ofile);
|
||||||
fwriteint32_t(relpos, ofile);
|
fwriteint32_t(relpos, ofile);
|
||||||
fwriteint32_t(0L, ofile); /* no line numbers - we don't do 'em */
|
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 */
|
fwriteint16_t(0, ofile); /* again, no line numbers */
|
||||||
fwriteint32_t(flags, ofile);
|
fwriteint32_t(flags, ofile);
|
||||||
}
|
}
|
||||||
|
@ -948,6 +980,13 @@ static void coff_write_relocs(struct Section *s)
|
||||||
{
|
{
|
||||||
struct Reloc *r;
|
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) {
|
for (r = s->head; r; r = r->next) {
|
||||||
fwriteint32_t(r->address, ofile);
|
fwriteint32_t(r->address, ofile);
|
||||||
fwriteint32_t(r->symbol + (r->symbase == REAL_SYMBOLS ? initsym :
|
fwriteint32_t(r->symbol + (r->symbase == REAL_SYMBOLS ? initsym :
|
||||||
|
|
|
@ -137,6 +137,8 @@
|
||||||
#define IMAGE_SCN_LNK_REMOVE 0x00000800
|
#define IMAGE_SCN_LNK_REMOVE 0x00000800
|
||||||
#define IMAGE_SCN_LNK_COMDAT 0x00001000
|
#define IMAGE_SCN_LNK_COMDAT 0x00001000
|
||||||
|
|
||||||
|
#define IMAGE_SCN_MAX_RELOC 0xffff
|
||||||
|
|
||||||
#define IMAGE_SCN_MEM_FARDATA 0x00008000
|
#define IMAGE_SCN_MEM_FARDATA 0x00008000
|
||||||
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
|
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
|
||||||
#define IMAGE_SCN_MEM_16BIT 0x00020000
|
#define IMAGE_SCN_MEM_16BIT 0x00020000
|
||||||
|
|
Loading…
Reference in a new issue