Fix em_led -u name when memory allocator moves ALLOMODL.
Option -u was passing an offset from modulptr(0) in ALLOMODL to the string in argv. If entername() would move ALLOMODL to make room in ALLOGCHR, then the offset would become invalid, so the string would get lost. This fix copies the string into ALLOMODL. This was often not a problem because the initial size of ALLOGCHR in mach.h is probably large enough for -u. This became a problem when I caused the initial allocations to fail, and then only because the B runtime uses -u.
This commit is contained in:
parent
f09f14cd4d
commit
4fdfa3177e
|
@ -15,6 +15,7 @@ static char rcsid[] = "$Id$";
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
#include <out.h>
|
#include <out.h>
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@ -36,7 +37,7 @@ static first_pass();
|
||||||
static uint32_t number(const char *);
|
static uint32_t number(const char *);
|
||||||
static void setlign(int, uint32_t);
|
static void setlign(int, uint32_t);
|
||||||
static void setbase(int, uint32_t);
|
static void setbase(int, uint32_t);
|
||||||
static struct outname *makename();
|
static void enterundef(const char *, int);
|
||||||
static pass1();
|
static pass1();
|
||||||
static evaluate();
|
static evaluate();
|
||||||
static void norm_commons();
|
static void norm_commons();
|
||||||
|
@ -129,8 +130,6 @@ first_pass(argv)
|
||||||
register char *argp;
|
register char *argp;
|
||||||
int sectno;
|
int sectno;
|
||||||
int h;
|
int h;
|
||||||
extern int atoi();
|
|
||||||
extern char *strchr();
|
|
||||||
extern int hash();
|
extern int hash();
|
||||||
extern struct outname *searchname();
|
extern struct outname *searchname();
|
||||||
|
|
||||||
|
@ -235,7 +234,7 @@ first_pass(argv)
|
||||||
fatal("-u needs symbol name");
|
fatal("-u needs symbol name");
|
||||||
h = hash(*argv);
|
h = hash(*argv);
|
||||||
if (searchname(*argv, h) == (struct outname *)0)
|
if (searchname(*argv, h) == (struct outname *)0)
|
||||||
entername(makename(*argv), h);
|
enterundef(*argv, h);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
Verbose = 1;
|
Verbose = 1;
|
||||||
|
@ -330,17 +329,34 @@ setbase(int sectno, uint32_t base)
|
||||||
sect_base[sectno] = base;
|
sect_base[sectno] = base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct outname *
|
/*
|
||||||
makename(string)
|
* Do -u name by entering the undefined name in the symbol table.
|
||||||
char *string;
|
*/
|
||||||
|
static void
|
||||||
|
enterundef(const char *string, int hashval)
|
||||||
{
|
{
|
||||||
static struct outname namebuf;
|
struct outname namebuf;
|
||||||
|
size_t len;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
namebuf.on_foff = string - core_position - mems[ALLOMODL].mem_base;
|
/*
|
||||||
|
* Copy string to ALLOMODL, because entername() uses
|
||||||
|
* modulptr(namebuf.on_foff) but may move ALLOMODL to make
|
||||||
|
* room in ALLOGCHR. It also needs namebuf.on_foff != 0.
|
||||||
|
*/
|
||||||
|
len = strlen(string) + 1;
|
||||||
|
buf = core_alloc(ALLOMODL, 1 + len);
|
||||||
|
if (buf == NULL)
|
||||||
|
fatal("no space for -u %s", string);
|
||||||
|
memcpy(buf + 1, string, len);
|
||||||
|
|
||||||
|
namebuf.on_foff = buf + 1 - modulptr(0);
|
||||||
namebuf.on_type = S_UND + S_EXT;
|
namebuf.on_type = S_UND + S_EXT;
|
||||||
namebuf.on_valu = (long)0;
|
namebuf.on_valu = (long)0;
|
||||||
|
entername(&namebuf, hashval);
|
||||||
|
|
||||||
return &namebuf;
|
/* buf might have moved; find it again and free it. */
|
||||||
|
core_free(ALLOMODL, modulptr(namebuf.on_foff) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue