示例#1
0
int symbols_set(struct _symbols *symbols, char *name, int address)
{
  struct _symbols_data *symbols_data = NULL;

  symbols_data = symbols_find(symbols, name);

  if (symbols_data == NULL)
  {
    if (symbols_append(symbols, name, address) != 0)
    {
      return -1; 
    }

    symbols_data = symbols_find(symbols, name);
    symbols_data->flag_rw = 1;
  }
    else
  if (symbols_data->flag_rw == 1)
  {
    symbols_data->address = address;
  }
    else
  {
    return -1;
  }

  return 0;
}
示例#2
0
/**
 * Load text symbols from the file into supplied table.
 *
 * @param bc		the BFD context pointing to the file
 * @param st		the symbol table where symbols should be added
 */
static void
bfd_util_load_text(bfd_ctx_t *bc, symbols_t *st)
{
	long i;
	asymbol* empty;
	void *p;

	bfd_ctx_check(bc);
	g_assert(st != NULL);

	if (0 == bc->count)
		return;

	mutex_lock_fast(&bc->lock);

	g_assert(bc->symbols != NULL);

	empty = bfd_make_empty_symbol(bc->handle);
	symbols_lock(st);

	for (
		i = 0, p = bc->symbols;
		i < bc->count;
		i++, p = ptr_add_offset(p, bc->symsize)
	) {
		asymbol *sym;
		symbol_info syminfo;

		sym = bfd_minisymbol_to_symbol(bc->handle, bc->dynamic, p, empty);
		bfd_get_symbol_info(bc->handle, sym, &syminfo);

		if ('T' == syminfo.type || 't' == syminfo.type) {
			const char *name = bfd_asymbol_name(sym);

			if (name != NULL && name[0] != '.') {
				void *addr = ulong_to_pointer(syminfo.value);
				symbols_append(st, addr, name);
			}
		}
	}

	symbols_unlock(st);
	mutex_unlock_fast(&bc->lock);
}
示例#3
0
int assemble(struct _asm_context *asm_context)
{
  char token[TOKENLEN];
  int token_type;

  while(1)
  {
    token_type = tokens_get(asm_context, token, TOKENLEN);
#ifdef DEBUG
    printf("%d: <%d> %s\n", asm_context->line, token_type, token);
#endif
    if (token_type == TOKEN_EOF) break;

    if (token_type == TOKEN_EOL)
    {
      if (asm_context->macros.stack_ptr == 0) { asm_context->line++; }
    }
      else
    if (token_type == TOKEN_LABEL)
    {
      int param_count_temp;
      if (macros_lookup(&asm_context->macros, token, &param_count_temp) != NULL)
      {
        print_already_defined(asm_context, token);
        return -1;
      }

      if (symbols_append(&asm_context->symbols, token, asm_context->address / asm_context->bytes_per_address) == -1)
      {
        return -1;
      }
    }
      else
    if (token_type == TOKEN_POUND || IS_TOKEN(token,'.'))
    {
      token_type = tokens_get(asm_context, token, TOKENLEN);
#ifdef DEBUG
    printf("%d: <%d> %s\n", asm_context->line, token_type, token);
#endif
      if (token_type == TOKEN_EOF) break;

      if (strcasecmp(token, "define") == 0)
      {
        if (macros_parse(asm_context, IS_DEFINE) != 0) return -1;
      }
        else
      if (strcasecmp(token, "ifdef") == 0)
      {
        parse_ifdef(asm_context, 0);
      }
        else
      if (strcasecmp(token, "ifndef") == 0)
      {
        parse_ifdef(asm_context, 1);
      }
        else
      if (strcasecmp(token, "if") == 0)
      {
        parse_if(asm_context);
      }
        else
      if (strcasecmp(token, "endif") == 0)
      {
        if (asm_context->ifdef_count < 1)
        {
          printf("Error: unmatched .endif at %s:%d\n", asm_context->filename, asm_context->ifdef_count);
          return -1;
        }
        return 0;
      }
        else
      if (strcasecmp(token, "else") == 0)
      {
        if (asm_context->ifdef_count < 1)
        {
          printf("Error: unmatched .else at %s:%d\n", asm_context->filename, asm_context->ifdef_count);
          return -1;
        }
        return 2;
      }
        else
      if (strcasecmp(token, "include") == 0)
      {
        if (parse_include(asm_context) != 0) return -1;
      }
        else
      if (strcasecmp(token, "binfile") == 0)
      {
        if (parse_binfile(asm_context) != 0) return -1;
      }
        else
      if (strcasecmp(token, "code") == 0)
      {
        asm_context->segment = SEGMENT_CODE;
      }
        else
      if (strcasecmp(token, "bss") == 0)
      {
        asm_context->segment = SEGMENT_BSS;
      }
        else
      if (strcasecmp(token, "msp430_cpu4") == 0)
      {
        asm_context->msp430_cpu4 = 1;
      }
        else
      if (strcasecmp(token, "macro") == 0)
      {
        if (macros_parse(asm_context, IS_MACRO) != 0) return -1;
      }
        else
      if (strcasecmp(token, "pragma") == 0)
      {
        if (parse_pragma(asm_context) != 0) return -1;
      }
        else
      if (strcasecmp(token, "device") == 0)
      {
        if (parse_device(asm_context) != 0) return -1;
      }
        else
      if (strcasecmp(token, "set") == 0)
      {
        if (parse_set(asm_context) != 0) return -1;
      }
        else
      if (strcasecmp(token, "export") == 0)
      {
        if (parse_export(asm_context) != 0) return -1;
      }
        else
      if (strcasecmp(token, "equ") == 0 || strcasecmp(token, "def")==0)
      {
        if (parse_equ(asm_context) != 0) return -1;
      }
        else
      {
        int ret = check_for_directive(asm_context, token);
        if (ret == 2) break;
        if (ret == -1) return -1;
        if (ret != 1)
        {
          printf("Error: Unknown directive '%s' at %s:%d.\n", token, asm_context->filename, asm_context->line);
          return -1;
        }
      }
    }
      else
    if (token_type == TOKEN_STRING)
    {
      int ret = check_for_directive(asm_context, token);
      if (ret == 2) break;
      if (ret == -1) return -1;
      if (ret != 1) 
      {
        int start_address = asm_context->address;
        char token2[TOKENLEN];
        int token_type2;

        token_type2 = tokens_get(asm_context, token2, TOKENLEN);

        if (strcasecmp(token2, "equ") == 0)
        {
          //token_type2 = tokens_get(asm_context, token2, TOKENLEN);
          int ptr = 0;
          int ch = '\n';

          while(1)
          {
            ch = tokens_get_char(asm_context);
            if (ch == EOF || ch == '\n') break;
            if (ch == '*' && ptr > 0 && token2[ptr-1] == '/')
            {
              macros_strip_comment(asm_context);
              ptr--;
              continue;
            }

            token2[ptr++] = ch;
            if (ptr == TOKENLEN-1)
            {
              printf("Internal Error: token overflow at %s:%d.\n", __FILE__, __LINE__);
              return -1;
            }
          }
          token2[ptr] = 0;
          tokens_unget_char(asm_context, ch);
          macros_strip(token2);
          macros_append(asm_context, token, token2, 0);
        }
          else
        {
          tokens_push(asm_context, token2, token_type2);

          ret = asm_context->parse_instruction(asm_context, token);

          if (asm_context->pass == 2 &&
              asm_context->list != NULL &&
              asm_context->include_count == 0)
          {
            asm_context->list_output(asm_context, start_address);
            fprintf(asm_context->list, "\n");
          }

          if (ret < 0) return -1;

          if (asm_context->macros.stack_ptr == 0) { asm_context->line++; }
          asm_context->instruction_count++;

          if (asm_context->address > start_address)
          {
            asm_context->code_count += (asm_context->address - start_address);
          }
        }
      }
    }
      else
    {
      print_error_unexp(token, asm_context);
      return -1;
    }
  }

  if (asm_context->error == 1) { return -1; }

  return 0;
}
示例#4
0
int read_elf(char *filename, struct _memory *memory, uint8_t *cpu_type, struct _symbols *symbols)
{
FILE *in;
uint8_t e_ident[16];
int e_shoff;
int e_shentsize;
int e_shnum;
int e_shstrndx;
int n;
int start, end;
struct _elf32_shdr elf32_shdr;
long strtab_offset = 0;
get_int16_t get_int16;
get_int32_t get_int32;

  memory_clear(memory);
  //memset(dirty, 0, memory->size);

  start = -1;
  end = -1;

  in = fopen(filename, "rb");
  if (in == 0)
  {
    return -1;
  }

  memset(e_ident, 0, 16);
  n = fread(e_ident, 1, 16, in);

  if (e_ident[0] != 0x7f || e_ident[1] != 'E' ||
      e_ident[2] != 'L' || e_ident[3] != 'F')
  {
    //printf("Not an ELF file.\n");
    fclose(in);
    return -2;
  }

  #define EI_CLASS 4   // 1=32 bit, 2=64 bit
  #define EI_DATA 5    // 1=little endian, 2=big endian
  #define EI_OSABI 7   // 0=SysV, 255=Embedded

  if (e_ident[EI_CLASS] != 1) // let's let other stuff in || e_ident[7]!=0xff)
  {
    printf("ELF Error: e_ident shows incorrect type\n");
    fclose(in);
    return -1;
  }

  // EI_DATA
  if (e_ident[EI_DATA] == 1)
  {
    memory->endian = ENDIAN_LITTLE;
    get_int16 = get_int16_le; 
    get_int32 = get_int32_le; 
  }
    else
  if (e_ident[EI_DATA] == 2)
  {
    memory->endian = ENDIAN_BIG;
    get_int16 = get_int16_be; 
    get_int32 = get_int32_be; 
  }
    else
  {
    printf("ELF Error: EI_DATA incorrect data encoding\n");
    fclose(in);
    return -1;
  }

  get_int16(in);
  n = get_int16(in);

  switch(n)
  {
    case 8:
    case 10:
      *cpu_type = CPU_TYPE_MIPS;
      break;
    case 40:
      *cpu_type = CPU_TYPE_ARM;
      break;
    case 83:
      *cpu_type = CPU_TYPE_AVR8;
      break;
    case 105:
      *cpu_type = CPU_TYPE_MSP430;
      break;
    case 118:
      *cpu_type = CPU_TYPE_DSPIC;
      break;
    default:
      printf("ELF Error: e_machine unknown\n");
      fclose(in);
      return -1;
  }

  fseek(in, 32, SEEK_SET);
  e_shoff = get_int32(in);
  fseek(in, 46, SEEK_SET);
  e_shentsize = get_int16(in);
  e_shnum = get_int16(in);
  e_shstrndx = get_int16(in);

  //printf("e_shoff=%d\n", e_shoff);
  //printf("e_shentsize=%d\n", e_shentsize);
  //printf("e_shnum=%d\n", e_shnum);
  //printf("e_shstrndx=%d\n", e_shstrndx);

  fseek(in, e_shoff + (e_shstrndx * e_shentsize) + 16, SEEK_SET);
  int stroffset = get_int32(in);
  char name[32];

  // Need to find .strtab so we can fill in symbol names
  for (n = 0; n < e_shnum; n++)
  {
    fseek(in, e_shoff + (n * e_shentsize), SEEK_SET);
    read_shdr(in, &elf32_shdr, get_int32);

    if (elf32_shdr.sh_type == SHT_STRTAB)
    {
      read_name(in, name, 32, stroffset + elf32_shdr.sh_name);
      if (strcmp(name, ".strtab") == 0)
      {
        strtab_offset = elf32_shdr.sh_offset;
        break;
      }
    }
  }

  for (n = 0; n < e_shnum; n++)
  {
    // FIXME - a little inefficient eh?
    fseek(in, e_shoff + (n * e_shentsize), SEEK_SET);
    read_shdr(in, &elf32_shdr, get_int32);

    read_name(in, name, 32, stroffset + elf32_shdr.sh_name);

    //printf("name=%s\n", name);
    //int is_text = strncmp(name, ".text", 5) == 0 ? 1 : 0;
    int is_text = (elf32_shdr.sh_flags & SHF_EXECINSTR) != 0 ? 1 : 0;
    if (is_text ||
        strncmp(name, ".data", 5) == 0 || strcmp(name, ".vectors") == 0)
    {
      if (is_text)
      {
        if (start == -1) { start = elf32_shdr.sh_addr; }
        else if (start > elf32_shdr.sh_addr) { start = elf32_shdr.sh_addr; }

        if (end == -1) { end = elf32_shdr.sh_addr + elf32_shdr.sh_size - 1; }
        else if (end < elf32_shdr.sh_addr + elf32_shdr.sh_size) { end = elf32_shdr.sh_addr+elf32_shdr.sh_size - 1; }
      }

      long marker = ftell(in);
      fseek(in, elf32_shdr.sh_offset, SEEK_SET);

      int n;
      for (n = 0; n < elf32_shdr.sh_size; n++)
      {
        if (elf32_shdr.sh_addr + n >= memory->size) break;
        memory_write_m(memory, elf32_shdr.sh_addr + n, getc(in)); 
      }

      fseek(in, marker, SEEK_SET);

      printf("Loaded %d %s bytes from 0x%04x\n", n, name, elf32_shdr.sh_addr);
    }
      else
    if (elf32_shdr.sh_type == SHT_SYMTAB && symbols != NULL)
    {
      long marker = ftell(in);
      fseek(in, elf32_shdr.sh_offset, SEEK_SET);

      for (n = 0; n < elf32_shdr.sh_size; n += 16)
      {
        char name[128];

        struct _elf32_sym elf32_sym;
        elf32_sym.st_name = get_int32(in);
        elf32_sym.st_value = get_int32(in);
        elf32_sym.st_size = get_int32(in);
        elf32_sym.st_info = getc(in);
        elf32_sym.st_other = getc(in);
        elf32_sym.st_shndx = get_int16(in);

        read_name(in, name, 128, strtab_offset + elf32_sym.st_name);

        printf("symbol %12s 0x%04x\n", name, elf32_sym.st_value);
        if (elf32_sym.st_info != STT_NOTYPE &&
            elf32_sym.st_info != STT_SECTION &&
            elf32_sym.st_info != STT_FILE)
        {
          symbols_append(symbols, name, elf32_sym.st_value);
        }
      }
      fseek(in, marker, SEEK_SET);
    }
  }

  memory->low_address = start;
  memory->high_address = end;

  fclose(in);

  return start;
}