Beispiel #1
0
ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
{
    const char *start_symbol;
    unsigned long addr = 0;
    int pe_type = 0;

    if (find_elf_sym(symtab_section, "_WinMain@16"))
        pe_type = PE_GUI;
    else
    if (TCC_OUTPUT_DLL == s1->output_type) {
        pe_type = PE_DLL;
        /* need this for 'tccelf.c:relocate_section()' */
        s1->output_type = TCC_OUTPUT_EXE;
    }

    start_symbol =
        TCC_OUTPUT_MEMORY == s1->output_type
        ? PE_GUI == pe_type ? "_runwinmain" : NULL
        : PE_DLL == pe_type ? "__dllstart@12"
        : PE_GUI == pe_type ? "_winstart" : "_start"
        ;

    /* grab the startup code from libtcc1 */
    if (start_symbol)
        add_elf_sym(symtab_section,
            0, 0,
            ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
            SHN_UNDEF, start_symbol);

    if (0 == s1->nostdlib) {
        tcc_add_library(s1, "tcc1");
#ifdef __CYGWIN__
        tcc_add_library(s1, "cygwin1");
#else
        tcc_add_library(s1, "msvcrt");
#endif
        tcc_add_library(s1, "kernel32");
        if (PE_DLL == pe_type || PE_GUI == pe_type) {
            tcc_add_library(s1, "user32");
            tcc_add_library(s1, "gdi32");
        }
    }

    if (start_symbol) {
        addr = (unsigned long)tcc_get_symbol_err(s1, start_symbol);
        if (s1->output_type == TCC_OUTPUT_MEMORY && addr)
            /* for -run GUI's, put '_runwinmain' instead of 'main' */
            add_elf_sym(symtab_section,
                    addr, 0,
                    ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
                    text_section->sh_num, "main");
    }

    if (pe) {
        pe->type = pe_type;
        pe->start_addr = addr;
    }
}
uint32_t SymbolTable::addSymbol(uint32_t name, uint64_t value, uint64_t size, uint8_t bind, uint8_t type, uint32_t other, uint16_t shndx){

    if (elfFile->is64Bit()){
        Symbol64* sym = new Symbol64(this, NULL, symbols.size());
        Elf64_Sym symEntry;
        symEntry.st_name = name;
        symEntry.st_value = value;
        symEntry.st_size = size;
        symEntry.st_info = ELF64_ST_INFO(bind,type);
        symEntry.st_other = other;
        symEntry.st_shndx = shndx;

        memcpy(sym->charStream(), &symEntry, Size__64_bit_Symbol);
        symbols.append(sym);
        sizeInBytes += Size__64_bit_Symbol;
    } else {
        Symbol32* sym = new Symbol32(this, NULL, symbols.size());
        Elf32_Sym symEntry;
        symEntry.st_name = name;
        symEntry.st_value = (uint32_t)value;
        symEntry.st_size = (uint32_t)size;
        symEntry.st_info = ELF32_ST_INFO(bind,type);
        symEntry.st_other = other;
        symEntry.st_shndx = shndx;

        memcpy(sym->charStream(), &symEntry, Size__32_bit_Symbol);
        symbols.append(sym);
        sizeInBytes += Size__32_bit_Symbol;
    }

    //    sortSymbols();
    verify();
    return symbols.size()-1;
}
Beispiel #3
0
static void newSym32(char *name,elfull value,elfull size,uint8_t bind,
                     uint8_t type,unsigned shndx)
{
  struct Symbol32Node *elfsym = addSymbol32(name);

  setval(be,elfsym->s.st_value,4,value);
  setval(be,elfsym->s.st_size,4,size);
  elfsym->s.st_info[0] = ELF32_ST_INFO(bind,type);
  setval(be,elfsym->s.st_shndx,2,shndx);
}
Beispiel #4
0
void prepare_symentry(Sym *symentry) {
	symentry->st_name = 1;
	symentry->st_value = 0;
	symentry->st_size = fs.st_size;
#ifdef BIT32
	symentry->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
#else
	symentry->st_info = ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT);
#endif
	symentry->st_other = STV_DEFAULT;
	symentry->st_shndx = IDX_DATA;
}
Beispiel #5
0
/* ------------------------------------------------------------- */
PUB_FN int pe_load_def_file(TCCState *s1, int fd)
{
    DLLReference *dllref;
    int state = 0, ret = -1;
    char line[400], dllname[80], *p;
    FILE *fp = fdopen(dup(fd), "rb");

    if (NULL == fp)
        goto quit;

    for (;;) {
        p = get_line(line, sizeof line, fp);
        if (NULL == p)
            break;
        if (0 == *p || ';' == *p)
            continue;
        switch (state) {
        case 0:
            if (0 != strnicmp(p, "LIBRARY", 7))
                goto quit;
            strcpy(dllname, trimfront(p+7));
            ++state;
            continue;

        case 1:
            if (0 != stricmp(p, "EXPORTS"))
                goto quit;
            ++state;
            continue;

        case 2:
            dllref = tcc_malloc(sizeof(DLLReference) + strlen(dllname));
            strcpy(dllref->name, dllname);
            dllref->level = 0;
            dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
            ++state;

        default:
            add_elf_sym(s1->dynsymtab_section,
                s1->nb_loaded_dlls, 0,
                ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), 0,
                text_section->sh_num, p);
            continue;
        }
    }
    ret = 0;
quit:
    if (fp)
        fclose(fp);
    if (ret)
        error_noabort("unrecognized export definition file format");
    return ret;
}
Beispiel #6
0
Datei: pe.c Projekt: HarryR/sanos
int pe_load_def_file(TCCState *s1, int fd) {
  DLLReference *dllref;
  int state = 0, ret = -1, hint;
  char line[400], dllname[80], *p, *ordinal;
  FILE *fp = fdopen(dup(fd), "rb");
  if (fp == NULL) goto quit;

  for (;;) {
    p = get_line(line, sizeof line, fp);
    if (p == NULL) break;
    if (*p == 0 || *p == ';') continue;
    switch (state) {
      case 0:
        if (strncasecmp(p, "LIBRARY", 7) != 0) goto quit;
        strcpy(dllname, trimfront(p + 7));
        ++state;
        continue;

      case 1:
        if (strcasecmp(p, "EXPORTS") != 0) goto quit;
        ++state;
        continue;

      case 2:
        dllref = tcc_malloc(sizeof(DLLReference) + strlen(dllname));
        strcpy(dllref->name, dllname);
        dllref->level = 0;
        dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
        ++state;

      default:
        hint = 0;
        ordinal = strchr(p, '@');
        if (ordinal) {
          *ordinal = 0;
          trimback(p, ordinal);
          ordinal++;
          hint = atoi(ordinal);
        }
        add_elf_sym(s1->dynsymtab_section, s1->nb_loaded_dlls, 0, 
                    ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), hint, 
                    text_section->sh_num, p);
        continue;
    }
  }
  ret = 0;

quit:
  if (fp) fclose(fp);
  if (ret) error_noabort("unrecognized export definition file format");
  return ret;
}
/**
This function sets the Elf Symbol fields
@internalComponent
@released
@param aSym The Symbol representation
@param aElfSym The Elf Symbol
@param aCodeIndex The index at which this Symbol refers to in the code section where, we have the ordinal number
*/
void ElfProducer::SetSymolFields(Symbol *aSym, Elf32_Sym* aElfSym, PLUINT32 aCodeIndex) {
	
	aElfSym->st_other = STV_DEFAULT;
	
	aElfSym->st_info = (PLUCHAR) (ELF32_ST_INFO(STB_GLOBAL, aSym->CodeDataType()));
	aElfSym->st_value	= (aCodeIndex - 1)*sizeof(Elf32_Word);
	
	if(aSym->CodeDataType() == SymbolTypeCode){
		aElfSym->st_size	= sizeof(Elf32_Word);
	}else{
		aElfSym->st_size	= aSym->SymbolSize();
	}
	aElfSym->st_shndx = CODE_SECTION;
}
Beispiel #8
0
/* changesymbols() finds all symbols in a given symbol table that
 * appear in the namelist with the specified binding and alters their
 * binding strength.
 */
static int changesymbols(Elf32_Sym *symtab, char const *strtab, int count)
{
    Elf32_Sym  *sym;
    char const *name;
    int		touched;
    int		i;

    touched = FALSE;
    for (i = 0, sym = symtab ; i < count ; ++i, ++sym) {
	if (ELF32_ST_BIND(sym->st_info) != fromstrength)
	    continue;
	name = strtab + sym->st_name;
	if (!bsearch(&name, namelist, namecount, sizeof *namelist, qstrcmp))
	    continue;
	sym->st_info = ELF32_ST_INFO(tostrength, ELF32_ST_TYPE(sym->st_info));
	printf("%s \"%s\".\n", tostrengthtext, name);
	touched = TRUE;
    }
    return touched;
}
Beispiel #9
0
static void
elf_x86_x86_write_symtab_entry(unsigned char *bufp,
                               elf_symtab_entry *entry,
                               yasm_intnum *value_intn,
                               yasm_intnum *size_intn)
{
    YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
    YASM_WRITE_32I_L(bufp, value_intn);
    YASM_WRITE_32I_L(bufp, size_intn);

    YASM_WRITE_8(bufp, ELF32_ST_INFO(entry->bind, entry->type));
    YASM_WRITE_8(bufp, ELF32_ST_OTHER(entry->vis));
    if (entry->sect) {
        elf_secthead *shead =
            yasm_section_get_data(entry->sect, &elf_section_data);
        if (!shead)
            yasm_internal_error(N_("symbol references section without data"));
        YASM_WRITE_16_L(bufp, shead->index);
    } else {
        YASM_WRITE_16_L(bufp, entry->index);
    }
}
Beispiel #10
0
Datei: pe.c Projekt: HarryR/sanos
static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) {
  const char *start_symbol;
  unsigned long addr = 0;
  int pe_type = 0;
  int start_sym_index;

  if (find_elf_sym(symtab_section, "_WinMain@16")) {
    pe_type = PE_GUI;
  } else if (s1->output_type == TCC_OUTPUT_DLL) {
    pe_type = PE_DLL;
    // Need this for 'tccelf.c:relocate_section()'
    s1->output_type = TCC_OUTPUT_EXE;
  } else {
    pe_type = PE_EXE;
  }

  start_symbol = s1->start_symbol;
  if (!start_symbol) {
    start_symbol = pe_type == PE_DLL ? "_DllMain@12" : "mainCRTStartup";
  }
  start_sym_index = add_elf_sym(symtab_section, 0, 0,
                                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
                                SHN_UNDEF, start_symbol);
  tcc_get_symbol_err(s1, start_symbol);

  if (s1->nostdlib == 0) {
    tcc_add_library(s1, "c");
    tcc_add_library(s1, "os");
  }

  if (pe) {
    pe->type = pe_type;
    pe->start_sym_index = start_sym_index;
    pe->stub = s1->stub;
    pe->def = s1->def_file;
    pe->filealign = s1->filealign;
  }
}
Beispiel #11
0
/*
 * Search for a symbol by name and return the corresponding symbol
 * information.  If we're compiled _LP64, we just call Plookup_by_name
 * and return because ps_sym_t is defined to be an Elf64_Sym, which
 * is the same as a GElf_Sym.  In the _ILP32 case, we have to convert
 * Plookup_by_name's result back to a ps_sym_t (which is an Elf32_Sym).
 */
ps_err_e
ps_pglobal_sym(struct ps_prochandle *P, const char *object_name,
	const char *sym_name, ps_sym_t *symp)
{
#if defined(_ILP32)
	GElf_Sym sym;

	if (Plookup_by_name(P, object_name, sym_name, &sym) == 0) {
		symp->st_name = (Elf32_Word)sym.st_name;
		symp->st_value = (Elf32_Addr)sym.st_value;
		symp->st_size = (Elf32_Word)sym.st_size;
		symp->st_info = ELF32_ST_INFO(
		    GELF_ST_BIND(sym.st_info), GELF_ST_TYPE(sym.st_info));
		symp->st_other = sym.st_other;
		symp->st_shndx = sym.st_shndx;
		return (PS_OK);
	}

#elif defined(_LP64)
	if (Plookup_by_name(P, object_name, sym_name, symp) == 0)
		return (PS_OK);
#endif
	return (PS_NOSYM);
}
Beispiel #12
0
                 // (forces align and bss_end symbol defined)
};

object  *root_obj      = NULL;
global  *root_global   = NULL;  // global symbols

section *text_sections = NULL,
        *data_sections = NULL;

Elf32_Off text_offset = 0,      // virtual sections offsets (that is, in memory)
          data_offset = 0;
Elf32_Off data_file_offset = 0; // physical offset of data section (in file)

comp_desc comp;                 // a component meta-data

Elf32_Sym  text_end_sym = { 0, 0, 0, ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE), 0, SHN_ABS },
           data_end_sym = { 0, 0, 0, ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE), 0, SHN_ABS },
           bss_end_sym  = { 0, 0, 0, ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE), 0, SHN_ABS },
           img_end_sym  = { 0, 0, 0, ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE), 0, SHN_ABS };


//------------------------------------------------------------------------
// Uninitialized Data
//------------------------------------------------------------------------

mt   mtbl;                   // MUST be adjacent with the next array
char trash_space[ 20000 ];   // this space gets trashed by the method table


//------------------------------------------------------------------------
// Main Function
Beispiel #13
0
Datei: pe.c Projekt: HarryR/sanos
static int pe_check_symbols(struct pe_info *pe) {
  Elf32_Sym *sym;
  int sym_index, sym_end;
  int ret = 0;

  pe_align_section(text_section, 8);

  sym_end = symtab_section->data_offset / sizeof(Elf32_Sym);
  for (sym_index = 1; sym_index < sym_end; ++sym_index) {
    sym = (Elf32_Sym *) symtab_section->data + sym_index;
    if (sym->st_shndx == SHN_UNDEF) {
      const char *name = symtab_section->link->data + sym->st_name;
      unsigned type = ELF32_ST_TYPE(sym->st_info);
      int imp_sym = pe_find_import(pe->s1, name);
      struct import_symbol *is;

      if (imp_sym == 0) goto not_found;
      is = pe_add_import(pe, imp_sym);
      if (!is) goto not_found;

      if (type == STT_FUNC) {
        unsigned long offset = is->thk_offset;
        if (offset) {
          // Got aliased symbol, like stricmp and _stricmp
        } else {
          char buffer[100];

          offset = text_section->data_offset;
          // Add the 'jmp IAT[x]' instruction
          *(WORD *) section_ptr_add(text_section, 8) = 0x25FF;

          // Add a helper symbol, will be patched later in pe_build_imports
          sprintf(buffer, "IAT.%s", name);
          is->iat_index = put_elf_sym(symtab_section, 0, sizeof(DWORD),
                                      ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
                                      0, SHN_UNDEF, buffer);
          put_elf_reloc(symtab_section, text_section, offset + 2, R_386_32, is->iat_index);
          is->thk_offset = offset;
        }

        // tcc_realloc might have altered sym's address
        sym = (Elf32_Sym *) symtab_section->data + sym_index;

        // Patch the original symbol
        sym->st_value = offset;
        sym->st_shndx = text_section->sh_num;
        sym->st_other &= ~1; // Do not export
        continue;
      }

      if (type == STT_OBJECT) { 
        if (is->iat_index == 0) {
          // Original symbol will be patched later in pe_build_imports
          is->iat_index = sym_index;
          continue;
        }
      }

    not_found:
      error_noabort("undefined symbol '%s'", name);
      ret = 1;
    } else if (pe->s1->rdynamic && ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
      // If -rdynamic option, then export all non local symbols
      sym->st_other |= 1;
    }
  }
  return ret;
}
Beispiel #14
0
int main(int argc, char **argv)
{
  ELF_SPEC_HEADER *curr = NULL, *progh = NULL , *new_dynsym = NULL, *new_dynstr = NULL,*newhash=NULL;
 



  int new_symbol_index=-1;
  int i=0;/* A Counter */
 
  char *contents;
  new_symbol_name=(char *)malloc(sizeof("new_symbol_avijit"));
  char *tmp="new_symbol_avijit";
  for(i=0;i<sizeof("new_symbol_avijit");i++)
    new_symbol_name[i]=*(tmp+i);
  new_symbol_name[sizeof("new_symbol_avijit")-1]='\0';
  new_symbol_size=sizeof("new_symbol_avijit");
  char *dynsym_data,*dynstr_data;
  int *hash_data;
  int first_load_segment = 1;
  unsigned long hash_bucket=elf_hash(new_symbol_name);
  Elf32_Addr dynamic_section_addr=0;
  ELF_SPEC_HEADER *dynamic_segment = NULL;

 

  if (argc != 4){
    fprintf(stderr, "Usage: %s <input-file> <output-file> <new data>\n",argv[0]);
    return 0;
  }
  printf("Displaying the data to be inserted: %s\n",argv[3]);
  if(init(argv[1])){
    exit(1);
  }
  find_sections();
  extra_pages=calculate_extra_pages(sizeof(*argv[3]));
  calculate_new_addresses(new_symbol_size);
  printf("Extra Pages required: %d\n",extra_pages);

  curr=melf_sectionAdd(melf);
  new_dynsym = melf_sectionAdd(melf);
  new_dynstr = melf_sectionAdd(melf);
  newhash=melf_sectionAdd(melf);


  newdata_size=PAGE_SIZE*extra_pages-dynsym_size-dynstr_size-hash_size;
  printf("new data size recalculated: 0x%x\n",newdata_size);
  contents=(char *)malloc(newdata_size);
  dynsym_data=(char *)malloc(old_dynsym_size+melf_sectionGetEntrySize(melf,old_dynsym));
  dynstr_data=(char *)malloc(old_dynstr_size+new_symbol_size);
  hash_data=(int*)malloc(old_hash_size+4);
  strcpy(contents, argv[3]);   
    
  /* Fixing dynsym section */
  void *prev_dynsym_contents=melf_sectionGetContent(melf,old_dynsym);
  bcopy(prev_dynsym_contents,dynsym_data,old_dynsym_size);
  /* Calculating the index of the symbol to be added */
  new_symbol_index=old_dynsym_size/melf_sectionGetEntrySize(melf,old_dynsym);

  printf(".dynsym contents:\n");
  for(i=0;i<old_dynsym_size;i++)
    printf("%c ",dynsym_data[i]>31?dynsym_data[i]:'.');
  printf("\n");
  /* Add the entry for pointing to corresponding entry in the .dynstr */
  char new_entry[16];
  for(i=0;i<16;i++)
    new_entry[i]=(char)0x0;
 
 /* Calculating the index of new symbol in the dynstr */
  int new_index=old_dynstr_size;   /* Remember that index in dynstr is really the offset from start of section */
  Elf32_Sym *elf_sym=(Elf32_Sym *)malloc(sizeof(Elf32_Sym));
  elf_sym->st_name=new_index;
  elf_sym->st_value=newdata_addr;
  elf_sym->st_size=new_symbol_size;
  elf_sym->st_info=ELF32_ST_INFO(STB_GLOBAL,STT_OBJECT);
  elf_sym->st_other=ELF32_ST_OTHER(STV_DEFAULT);
  elf_sym->st_shndx=(Elf32_Half)melf_sectionGetIndex(melf,curr);

  for(i=0;i<16;i++){
    dynsym_data[i+old_dynsym_size]=*(char *)((void*)elf_sym+i)/*new_entry[i]*/;
    printf("Emitting : 0x%d\n",new_entry[i]);
  }

      
  /* Change the pointer of new_dynsym to that of the old dynsym */

      
  melf_sectionSetContent(melf,new_dynsym,prev_dynsym_contents,old_dynsym_size);
  melf_sectionSetType(melf,new_dynsym,SHT_PROGBITS);
  melf_sectionSetAddress(melf,new_dynsym,old_dynsym->spec.section.sh_addr);
  melf_sectionSetFlags(melf, new_dynsym, SHF_ALLOC);
     
  /* Set the dynsym section properly */
  melf_sectionSetAddress(melf,old_dynsym,dynsym_addr);
  melf_sectionSetContent(melf,old_dynsym,dynsym_data,old_dynsym_size+melf_sectionGetEntrySize(melf,old_dynsym));


  /* Fixing dynstr */
  void *prev_dynstr_contents=melf_sectionGetContent(melf,old_dynstr);
  bcopy(prev_dynstr_contents,dynstr_data,old_dynstr_size);
  for(i=0;i<new_symbol_size;i++)
    dynstr_data[old_dynstr_size+i]=new_symbol_name[i];
    
  printf(".dynstr contents:\n");
  printf("New symbol size= %d\n",new_symbol_size);
  for(i=0;i<old_dynstr_size+new_symbol_size;i++)
    printf("%c ",dynstr_data[i]>31?dynstr_data[i]:'.');
  printf("\n");
  printf("Contents copied dynstr: %s\n",dynstr_data);

  melf_sectionSetContent(melf,new_dynstr,prev_dynstr_contents,old_dynstr_size);
  melf_sectionSetType(melf,new_dynstr,SHT_PROGBITS);
  melf_sectionSetAddress(melf,new_dynstr,old_dynstr->spec.section.sh_addr);
  melf_sectionSetFlags(melf, new_dynstr, SHF_ALLOC);

  melf_sectionSetAddress(melf,old_dynstr,dynstr_addr);
  melf_sectionSetContent(melf,old_dynstr,dynstr_data,old_dynstr_size+new_symbol_size);
      
  /* Done Fixing dynsym and dynstr */

   
 

   
  /* Fix hash section */


  void *prev_hash_contents=melf_sectionGetContent(melf,old_hash);
  hash_data=malloc(old_hash_size+4);
  bcopy(prev_hash_contents,hash_data,old_hash_size);
  melf_sectionSetContent(melf,newhash,prev_hash_contents,old_hash_size);
  melf_sectionSetType(melf,newhash,SHT_PROGBITS/*melf_sectionGetType(melf,old_hash)*/);
  melf_sectionSetAddress(melf,newhash,old_hash->spec.section.sh_addr);
  melf_sectionSetFlags(melf, newhash,SHF_ALLOC/*melf_sectionGetFlags(melf,old_hash)*/);

  /* Calculate hash value of new symbol and insert it in the chain properly */
  printf("Printing out the original contents of .hash\n");
  for(i=0;i<old_hash->spec.section.sh_size/4;i++)
    printf("%d\n",(int)*(hash_data+i));
  add_new_chain(hash_bucket,hash_data,new_symbol_index);
  printf("Hash bucket is: %ld\n",hash_bucket%nbuckets);
  printf("Printing out the new hash table\n");
  for(i=0;i<sizeof(hash_data);i++)
    printf("0x%x\n",hash_data[i]&0xff);
  /* Set the hash table properly */
  melf_sectionSetAddress(melf,old_hash,hash_addr);
  melf_sectionSetContent(melf,old_hash,hash_data,old_hash_size+4);     
  /* Done Fixing hash section */

   


  if (!curr) {
    fprintf(stderr, "Cannot create new section\n");
    return 1;
  }

  melf_sectionSetType(melf, curr, SHT_PROGBITS);
  melf_sectionSetFlags(melf, curr, SHF_ALLOC);
  melf_sectionSetAddress(melf, curr, newdata_addr);
 
  melf_sectionSetContent(melf, curr, contents,newdata_size);	
  
  // change the segment map
	
  progh = melf_programGetEnum(melf);
  while (progh) {
    switch (melf_programGetType(melf, progh)) {
    case PT_PHDR:
      melf_programSetVirtualAddress(melf, progh,
				    melf_programGetVirtualAddress(melf, progh) -
				    PAGE_SIZE*extra_pages);
      melf_programSetPhysicalAddress(melf, progh,
				     melf_programGetPhysicalAddress(melf, progh) -
				     PAGE_SIZE*extra_pages);
      break;
    case PT_LOAD:
      if (first_load_segment) {
	melf_programSetVirtualAddress(melf, progh,
				      melf_programGetVirtualAddress(melf, progh) -
				      PAGE_SIZE*extra_pages);
	melf_programSetPhysicalAddress(melf, progh,
				       melf_programGetPhysicalAddress(melf, progh) -
				       PAGE_SIZE*extra_pages);
	melf_programSetPhysicalSize(melf, progh,
				    melf_programGetPhysicalSize(melf, progh) +
				    PAGE_SIZE*extra_pages);
	melf_programSetVirtualSize(melf, progh,
				   melf_programGetVirtualSize(melf, progh) +
				   PAGE_SIZE*extra_pages);
	first_load_segment = 0;
      } else
	progh->spec.program.p_offset += PAGE_SIZE*extra_pages;
      break;
    case PT_DYNAMIC:
      dynamic_section_addr=progh->spec.section.sh_addr;
      dynamic_segment=progh;

    case PT_INTERP:
    default:
      progh->spec.program.p_offset += PAGE_SIZE*extra_pages;
      break;
    }
    progh = melf_programEnumNext(melf, progh);
  }
 

  if(!melf_dynamicSetTag(melf,old_dynamic,DT_SYMTAB,dynsym_addr)||
     !melf_dynamicSetTag(melf,old_dynamic,DT_STRTAB,dynstr_addr)||
     !melf_dynamicSetTag(melf,old_dynamic,DT_HASH,hash_addr)){
    fprintf(stderr,"Error in reassigning pointers iin .dynamic\n");
    return 1;
  }
  melf_save(melf, argv[2]);
  melf_destroy(melf);
  return 0;
}
Beispiel #15
0
Elf_Scn *symtab_write_elf(Elf *e, struct sect * sects,
						  struct buffer *strtab_buf, struct buffer *shstrtab_buf)
{
  unsigned i, k;
  struct sym_info *sym;
  Elf32_Sym esym;

  Elf_Scn *scn, *relscn, *tmpscn;
  Elf_Data *data, *reldata;
  Elf32_Shdr *shdr, *relshdr;

  struct buffer buf;
  struct buffer *relbuf;

  struct sect *s;

  buffer_init(&buf);

  esym.st_name = 0;
  esym.st_value = 0;
  esym.st_size = 0;
  esym.st_info = 0;
  esym.st_other = 0;
  esym.st_shndx = 0;
  buffer_writemem(&buf, &esym, sizeof(esym));

  relbuf = malloc(0);
  for (s = sects, k = 0; s != NULL; s = s->next, k++)
	{
	  relbuf = realloc(relbuf, (k+1)*sizeof(struct buffer));
	  buffer_init(&relbuf[k]);
	}

  for (i = 0; i < SYMTAB_SIZE; i++)
    {
      for (sym = symtab[i]; sym != NULL; sym = sym->next)
        {
          if (sym->symbol[0] != '.' || sym->relocs != NULL)
            {
			  struct reloc_info size;
			  int type = STT_NOTYPE;
			  int bind = STB_LOCAL;
			  if (!sym->defined || sym->bind == SYM_BIND_GLOBAL)
				{
				  bind = STB_GLOBAL;
				}

			  esym.st_name = strtab_buf->pos;
			  buffer_writestr(strtab_buf, sym->symbol);

			  esym.st_value = sym->addr;
			  
			  size = expr_evaluate(sym->size);
			  if (size.symbol != NULL) {
				eprintf("Cannot relocate symbol size");
				exit(EXIT_FAILURE);
			  }
			  esym.st_size = size.intval;

			  if (strcmp(sym->type, "@function") == 0)
				type = STT_FUNC;
			  if (strcmp(sym->type, "@object") == 0)
				type = STT_OBJECT;
			  esym.st_info = ELF32_ST_INFO(bind, type);

			  esym.st_other = ELF32_ST_VISIBILITY(STV_DEFAULT);

			  tmpscn = section_find(e, sym->section, shstrtab_buf);
			  if (tmpscn == NULL && sym->section != NULL)
				tmpscn = section_find(e, pile_name(pile_match(sym->section)), shstrtab_buf);
			  esym.st_shndx = tmpscn != NULL ? elf_ndxscn(tmpscn) : 0;

			  if (sym->relocs != NULL) {
				struct sym_reloc_info *r;
				for (r = sym->relocs; r != NULL; r = r->next) {
				  Elf32_Rela rel;
				  rel.r_offset = r->addr;
				  rel.r_info = ELF32_R_INFO(buf.pos/sizeof(esym), r->type);
				  rel.r_addend = r->addend;
				  for (s = sects, k = 0; s != NULL; s = s->next, k++)
					{
					  if (strcmp(s->name, r->sect) == 0)
						{
						  buffer_writemem(&relbuf[k], &rel, sizeof(rel));
						}
					}
				}
			  }

			  buffer_writemem(&buf, &esym, sizeof(esym));
			}
        }
    }

  scn = xelf_newscn(e);

  shdr = xelf32_getshdr(scn);
  shdr->sh_name = shstrtab_buf->pos;
  buffer_writestr(shstrtab_buf, ".symtab");
  shdr->sh_type = SHT_SYMTAB;
  shdr->sh_flags = 0;

  data = xelf_newdata(scn);
  data->d_align = 4;
  data->d_off = 0;
  data->d_type = ELF_T_SYM;
  data->d_version = EV_CURRENT;
  data->d_buf = buf.data;
  data->d_size = buf.pos;

  for (s = sects, k = 0; s != NULL; s = s->next, k++)
	{
	  if (relbuf[k].pos > 0)
		{
		  char *relname;

		  relscn = xelf_newscn(e);
	  
		  relshdr = xelf32_getshdr(relscn);
		  relshdr->sh_name = shstrtab_buf->pos;
		  relname = malloc(strlen(s->name)+6);
		  strcpy(relname, ".rela");
		  strcat(relname, s->name);
		  buffer_writestr(shstrtab_buf, relname);

		  relshdr->sh_type = SHT_RELA;
		  shdr->sh_flags = 0;

		  reldata = xelf_newdata(relscn);
		  reldata->d_align = 4;
		  reldata->d_off = 0;
		  reldata->d_type = ELF_T_RELA;
		  reldata->d_version = EV_CURRENT;
		  reldata->d_buf = relbuf[k].data;
		  reldata->d_size = relbuf[k].pos;

		  relshdr->sh_link = elf_ndxscn(scn);
		  
		  tmpscn = section_find(e, s->name, shstrtab_buf);
		  relshdr->sh_info = tmpscn != NULL ? elf_ndxscn(tmpscn) : 0;
		}
	}

  return scn;
}