Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/misoc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3f7f0a31512d
Choose a base ref
...
head repository: m-labs/misoc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8a0beb4cfb81
Choose a head ref
  • 4 commits
  • 5 files changed
  • 1 contributor

Commits on Aug 1, 2015

  1. libbase: downstream users should provide fprintf.

    whitequark committed Aug 1, 2015
    Copy the full SHA
    13a50a9 View commit details
  2. Copy the full SHA
    d625c43 View commit details
  3. libdyld: add support for R_OR1K_{NONE,32,GLOB_DAT}.

    whitequark committed Aug 1, 2015
    Copy the full SHA
    344e1bc View commit details
  4. unwinder: update.

    whitequark committed Aug 1, 2015
    Copy the full SHA
    8a0beb4 View commit details
Showing with 44 additions and 40 deletions.
  1. +0 −15 software/libbase/console.c
  2. +10 −3 software/libbase/crt0-or1k.S
  3. +6 −4 software/libbase/exception.c
  4. +27 −17 software/libdyld/dyld.c
  5. +1 −1 software/unwinder
15 changes: 0 additions & 15 deletions software/libbase/console.c
Original file line number Diff line number Diff line change
@@ -78,18 +78,3 @@ int printf(const char *fmt, ...)

return len;
}

int fprintf(FILE *stream, const char *fmt, ...)
{
va_list args;
int len;
char outbuf[PRINTF_BUFFER_SIZE];

va_start(args, fmt);
len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
va_end(args);
outbuf[len] = 0;
putsnonl(outbuf);

return len;
}
13 changes: 10 additions & 3 deletions software/libbase/crt0-or1k.S
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@

#include <spr-defs.h>

#define EXCEPTION_STACK_SIZE (128+128)
#define EXCEPTION_STACK_SIZE (4*32)

#define HANDLE_EXCEPTION ; \
l.addi r1, r1, -EXCEPTION_STACK_SIZE ; \
@@ -193,11 +193,18 @@ _exception_handler:

/* Save return address */
l.or r14, r0, r9
/* send stack pointer as argument */
/* Calculate exception vector from handler address */
l.andi r3, r9, 0xf00
l.srli r3, r3, 8
/* Pass saved register state */
l.or r4, r0, r1
/* Extract exception PC */
l.mfspr r5, r0, SPR_EPCR_BASE
/* Extract exception effective address */
l.mfspr r6, r0, SPR_EEAR_BASE
/* Call exception handler with the link address as argument */
l.jal exception_handler
l.or r3, r0, r14
l.nop

/* Load return address */
l.or r9, r0, r14
10 changes: 6 additions & 4 deletions software/libbase/exception.c
Original file line number Diff line number Diff line change
@@ -2,12 +2,14 @@ void isr(void);

#ifdef __or1k__

#define EXTERNAL_IRQ 0x800
#define EXTERNAL_IRQ 0x8

void exception_handler(unsigned long vect, unsigned long *sp);
void exception_handler(unsigned long vect, unsigned long *sp)
void exception_handler(unsigned long vect, unsigned long *regs,
unsigned long pc, unsigned long ea);
void exception_handler(unsigned long vect, unsigned long *regs,
unsigned long pc, unsigned long ea)
{
if((vect & 0xf00) == EXTERNAL_IRQ) {
if(vect == EXTERNAL_IRQ) {
isr();
} else {
/* Unhandled exception */
44 changes: 27 additions & 17 deletions software/libdyld/dyld.c
Original file line number Diff line number Diff line change
@@ -3,26 +3,36 @@
#include <string.h>
#include <dyld.h>

static int fixup_rela(Elf32_Addr base, Elf32_Rela *rela,
const char *strtab, Elf32_Sym *symtab,
static int fixup_rela(struct dyld_info *info, Elf32_Rela *rela,
Elf32_Addr (*resolve_import)(const char *),
const char **error_out) {
Elf32_Sym *sym = NULL;
if(ELF32_R_SYM(rela->r_info) != 0)
sym = &symtab[ELF32_R_SYM(rela->r_info)];
sym = &info->symtab[ELF32_R_SYM(rela->r_info)];
Elf32_Addr value;

switch(ELF32_R_TYPE(rela->r_info)) {
case R_OR1K_NONE:
return 1; // Does nothing.

case R_OR1K_RELATIVE:
value = base + (sym ? sym->st_value : 0) + rela->r_addend;
value = info->base + (sym ? sym->st_value : 0) + rela->r_addend;
break;

case R_OR1K_32:
case R_OR1K_GLOB_DAT:
value = (Elf32_Addr)dyld_lookup(&info->strtab[sym->st_name], info);
if(value != 0)
break;
//fallthrough

case R_OR1K_JMP_SLOT:
value = resolve_import(&strtab[sym->st_name]);
value = resolve_import(&info->strtab[sym->st_name]);
if(value == 0) {
static char error[256];
snprintf(error, sizeof(error),
"ELF object has an unresolved symbol: %s", &strtab[sym->st_name]);
"ELF object has an unresolved symbol: %s",
&info->strtab[sym->st_name]);
*error_out = error;
return 0;
}
@@ -33,7 +43,7 @@ static int fixup_rela(Elf32_Addr base, Elf32_Rela *rela,
return 0;
}

*(Elf32_Addr*)(base + rela->r_offset) = value;
*(Elf32_Addr*)(info->base + rela->r_offset) = value;

return 1;
}
@@ -116,16 +126,6 @@ int dyld_load(void *shlib, Elf32_Addr base,
return 0;
}

for(int i = 0; i < relanum; i++) {
if(!fixup_rela(base, &rela[i], strtab, symtab, resolve_import, error_out))
return 0;
}

for(int i = 0; i < pltrelnum; i++) {
if(!fixup_rela(base, &pltrel[i], strtab, symtab, resolve_import, error_out))
return 0;
}

info->base = base;
info->init = (void*)(base + init);
info->strtab = strtab;
@@ -135,6 +135,16 @@ int dyld_load(void *shlib, Elf32_Addr base,
info->hash.bucket = &hash[2];
info->hash.chain = &hash[2 + info->hash.nbucket];

for(int i = 0; i < relanum; i++) {
if(!fixup_rela(info, &rela[i], resolve_import, error_out))
return 0;
}

for(int i = 0; i < pltrelnum; i++) {
if(!fixup_rela(info, &pltrel[i], resolve_import, error_out))
return 0;
}

return 1;
}

2 changes: 1 addition & 1 deletion software/unwinder