Esempio n. 1
0
// Relocate init code and then call a function at its new address.
// The passed function should be in the "init" section and must not
// return.
void __noreturn
reloc_preinit(void *f, void *arg)
{
    void (*func)(void *) __noreturn = f;
    if (!CONFIG_RELOCATE_INIT)
        func(arg);

    // Allocate space for init code.
    u32 initsize = SYMBOL(code32init_end) - SYMBOL(code32init_start);
    u32 codealign = SYMBOL(_reloc_min_align);
    void *codedest = memalign_tmp(codealign, initsize);
    void *codesrc = VSYMBOL(code32init_start);
    if (!codedest)
        panic("No space for init relocation.\n");

    // Copy code and update relocs (init absolute, init relative, and runtime)
    dprintf(1, "Relocating init from %p to %p (size %d)\n"
            , codesrc, codedest, initsize);
    s32 delta = codedest - codesrc;
    memcpy(codedest, codesrc, initsize);
    updateRelocs(codedest, VSYMBOL(_reloc_abs_start), VSYMBOL(_reloc_abs_end)
                 , delta);
    updateRelocs(codedest, VSYMBOL(_reloc_rel_start), VSYMBOL(_reloc_rel_end)
                 , -delta);
    updateRelocs(VSYMBOL(code32flat_start), VSYMBOL(_reloc_init_start)
                 , VSYMBOL(_reloc_init_end), delta);
    if (f >= codesrc && f < VSYMBOL(code32init_end))
        func = f + delta;

    // Call function in relocated code.
    barrier();
    func(arg);
}
Esempio n. 2
0
// Relocate init code and then call maininit() at new address.
static void
reloc_init(void)
{
    if (!CONFIG_RELOCATE_INIT) {
        maininit();
        return;
    }
    // Symbols populated by the build.
    extern u8 code32flat_start[];
    extern u8 _reloc_min_align;
    extern u32 _reloc_abs_start[], _reloc_abs_end[];
    extern u32 _reloc_rel_start[], _reloc_rel_end[];
    extern u32 _reloc_init_start[], _reloc_init_end[];
    extern u8 code32init_start[], code32init_end[];
    extern u32 _reloc_datalow_start[], _reloc_datalow_end[];
    extern u8 datalow_start[], datalow_end[], final_datalow_start[];

    // Allocate space for init code.
    u32 initsize = code32init_end - code32init_start;
    u32 codealign = (u32)&_reloc_min_align;
    void *codedest = memalign_tmp(codealign, initsize);
    if (!codedest)
        panic("No space for init relocation.\n");

    // Copy code and update relocs (init absolute, init relative, and runtime)
    dprintf(1, "Relocating low data from %p to %p (size %d)\n"
            , datalow_start, final_datalow_start, datalow_end - datalow_start);
    updateRelocs(code32flat_start, _reloc_datalow_start, _reloc_datalow_end
                 , final_datalow_start - datalow_start);
    dprintf(1, "Relocating init from %p to %p (size %d)\n"
            , code32init_start, codedest, initsize);
    s32 delta = codedest - (void*)code32init_start;
    memcpy(codedest, code32init_start, initsize);
    updateRelocs(codedest, _reloc_abs_start, _reloc_abs_end, delta);
    updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta);
    updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);

    // Call maininit() in relocated code.
    void (*func)(void) = (void*)afterReloc + delta;
    barrier();
    func();
}
Esempio n. 3
0
// Relocate init code and then call a function at its new address.
// The passed function should be in the "init" section and must not
// return.
void __noreturn
reloc_preinit(void *f, void *arg)
{
    void (*func)(void *) __noreturn = f;
    if (!CONFIG_RELOCATE_INIT)
        func(arg);
    // Symbols populated by the build.
    extern u8 code32flat_start[];
    extern u8 _reloc_min_align;
    extern u32 _reloc_abs_start[], _reloc_abs_end[];
    extern u32 _reloc_rel_start[], _reloc_rel_end[];
    extern u32 _reloc_init_start[], _reloc_init_end[];
    extern u8 code32init_start[], code32init_end[];

    // Allocate space for init code.
    u32 initsize = code32init_end - code32init_start;
    u32 codealign = (u32)&_reloc_min_align;
    void *codedest = memalign_tmp(codealign, initsize);
    if (!codedest)
        panic("No space for init relocation.\n");

    // Copy code and update relocs (init absolute, init relative, and runtime)
    dprintf(1, "Relocating init from %p to %p (size %d)\n"
            , code32init_start, codedest, initsize);
    s32 delta = codedest - (void*)code32init_start;
    memcpy(codedest, code32init_start, initsize);
    updateRelocs(codedest, _reloc_abs_start, _reloc_abs_end, delta);
    updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta);
    updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
    if (f >= (void*)code32init_start && f < (void*)code32init_end)
        func = f + delta;

    // Call function in relocated code.
    barrier();
    func(arg);
}