diff options
Diffstat (limited to 'arch/sandbox/cpu')
-rw-r--r-- | arch/sandbox/cpu/os.c | 37 | ||||
-rw-r--r-- | arch/sandbox/cpu/start.c | 12 |
2 files changed, 47 insertions, 2 deletions
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index a8d01e40011..c20491493fc 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -786,3 +786,40 @@ int os_mprotect_allow(void *start, size_t len) return mprotect(start, len, PROT_READ | PROT_WRITE); } + +void *os_find_text_base(void) +{ + char line[500]; + void *base = NULL; + int len; + int fd; + + /* + * This code assumes that the first line of /proc/self/maps holds + * information about the text, for example: + * + * 5622d9907000-5622d9a55000 r-xp 00000000 08:01 15067168 u-boot + * + * The first hex value is assumed to be the address. + * + * This is tested in Linux 4.15. + */ + fd = open("/proc/self/maps", O_RDONLY); + if (fd == -1) + return NULL; + len = read(fd, line, sizeof(line)); + if (len > 0) { + char *end = memchr(line, '-', len); + + if (end) { + unsigned long long addr; + + *end = '\0'; + if (sscanf(line, "%llx", &addr) == 1) + base = (void *)addr; + } + } + close(fd); + + return base; +} diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 2f5e6e95182..e22d65f6d9e 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -328,6 +328,10 @@ int main(int argc, char *argv[]) gd_t data; int ret; + memset(&data, '\0', sizeof(data)); + gd = &data; + gd->arch.text_base = os_find_text_base(); + ret = state_init(); if (ret) goto err; @@ -340,8 +344,6 @@ int main(int argc, char *argv[]) if (ret) goto err; - memset(&data, '\0', sizeof(data)); - gd = &data; #if CONFIG_VAL(SYS_MALLOC_F_LEN) gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif @@ -350,6 +352,12 @@ int main(int argc, char *argv[]) #endif setup_ram_buf(state); + /* + * Set up the relocation offset here, since sandbox symbols are always + * relocated by the OS before sandbox is entered. + */ + gd->reloc_off = (ulong)gd->arch.text_base; + /* Do pre- and post-relocation init */ board_init_f(0); |