예제 #1
0
    void serialize(std::ofstream &file, char ei_class, char ei_data)
    {
        // Readjust code offsets
        for (std::vector<ElfSection *>::iterator c = code.begin(); c != code.end(); c++)
            (*c)->getShdr().sh_addr += getAddr();

        // Apply relocations
        for (ElfSection *rel = elf->getSection(1); rel != NULL; rel = rel->getNext())
            if ((rel->getType() == SHT_REL) || (rel->getType() == SHT_RELA)) {
                ElfSection *section = rel->getInfo().section;
                if ((section->getType() == SHT_PROGBITS) && (section->getFlags() & SHF_EXECINSTR)) {
                    if (rel->getType() == SHT_REL)
                        apply_relocations((ElfRel_Section<Elf_Rel> *)rel, section);
                    else
                        apply_relocations((ElfRel_Section<Elf_Rela> *)rel, section);
                }
            }

        ElfSection::serialize(file, ei_class, ei_data);
    }
예제 #2
0
int main(int argc, char **argv)
{
   fprintf( stdout, header );

   DEBUG(( stderr, "main: parsing command line\n" ));
   if( parse_cmdline( argc, argv, options, countof(options) ) ) goto bail_out;
   if( warnings && (linker_options & OPT_ABORT_ON_WARN) ) goto bail_out;

   if( linker_options & OPT_SHOW_HELP )
   {
      help_msg( help_head, help_tail, options, countof(options) );
      goto bail_out;
   }

   if( !root_obj ) { error( "no input files" ); goto bail_out; }

   if( arrange_sections() ) goto bail_out;
   if( warnings && (linker_options & OPT_ABORT_ON_WARN) ) goto bail_out;

   adjust_symbols_values();
   register_symbols();
   resolve_references();

   if( warnings && (linker_options & OPT_ABORT_ON_WARN) ) goto bail_out;

   apply_relocations();

   if( warnings && (linker_options & OPT_ABORT_ON_WARN) ) goto bail_out;

   if( !(linker_options & OPT_MAKE_ORB) ) generate_mt();

   if( errors || warnings && (linker_options & OPT_ABORT_ON_WARN) ) goto bail_out;

   output_sections( output_filename );
   if( !(linker_options & OPT_MAKE_ORB) ) output_metadata( output_filename );
   if( warnings && (linker_options & OPT_ABORT_ON_WARN) ) goto bail_out;

   if( linker_options & OPT_XREF ) produce_xrefs( output_filename );

   if( errors || (warnings && (linker_options & OPT_ABORT_ON_WARN)))
      remove(output_filename);
   else if( linker_options & OPT_VERBOSE )
   {
      fprintf(stdout, "\n"
                      "******************************************************\n"
                      "** %s\n"
                      "**\n",
                      output_filename );

      if( linker_options & OPT_MAKE_ORB )
         fprintf( stdout, "** ORB generated as:\n" );
      else
         fprintf( stdout, "** Component generated as:\n" );

      fprintf(stdout, "** Text at 0x%08x, size 0x%08x\n"
                      "** Data at 0x%08x, size 0x%08x\n"
                      "** BSS  at 0x%08x, size 0x%08x\n",
                      comp.text.start, comp.text.size,
                      comp.data.start, comp.data.size,
                      comp.bss.start,  comp.bss.size
             );

      if( !(linker_options & OPT_MAKE_ORB) )
         fprintf( stdout, "** MTbl at 0x%08x, size 0x%08x\n", comp.mt.start, comp.mt.size );

      fprintf(stdout, "******************************************************\n"
                      "\n" );
   }

bail_out:
   //global_destruction(); // who cares? we exit anyway...

   if( errors || warnings )
      fprintf( stderr, "exiting with %d error(s), %d warning(s)\n", errors, warnings );

   if( warnings && (linker_options & OPT_ABORT_ON_WARN) ) return errors + warnings;

   return errors;
}
예제 #3
0
/***********************************************************************
 *           NE_LoadSegment
 */
BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
{
    WORD count;
    DWORD pos;
    const struct relocation_entry_s *rep;
    int size;
    SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
    SEGTABLEENTRY *pSeg = pSegTable + segnum - 1;

    if (pSeg->flags & NE_SEGFLAGS_LOADED)
    {
	/* self-loader ? -> already loaded it */
	if (pModule->ne_flags & NE_FFLAGS_SELFLOAD)
	    return TRUE;

	/* leave, except for DGROUP, as this may be the second instance */
	if (segnum != pModule->ne_autodata)
            return TRUE;
    }

    if (!pSeg->filepos) return TRUE;  /* No file image, just return */

    TRACE_(module)("Loading segment %d, hSeg=%04x, flags=%04x\n",
                    segnum, pSeg->hSeg, pSeg->flags );
    pos = pSeg->filepos << pModule->ne_align;
    if (pSeg->size) size = pSeg->size;
    else size = pSeg->minsize ? pSeg->minsize : 0x10000;

    if (pModule->ne_flags & NE_FFLAGS_SELFLOAD && segnum > 1)
    {
 	/* Implement self-loading segments */
 	SELFLOADHEADER *selfloadheader;
        void *oldstack;
        HFILE16 hFile16;
        WORD args[3];
        DWORD ret;

 	selfloadheader = MapSL( MAKESEGPTR(SEL(pSegTable->hSeg),0) );
        oldstack = getWOW32Reserved();
		setWOW32Reserved((void *)MAKESEGPTR(pModule->self_loading_sel,
                                                           0xff00 - sizeof(STACK16FRAME)));

        hFile16 = NE_OpenFile( pModule );
        TRACE_(dll)("Call LoadAppSegProc(hmodule=0x%04x,hf=%x,segnum=%d)\n",
                    pModule->self,hFile16,segnum );
        args[2] = pModule->self;
        args[1] = hFile16;
        args[0] = segnum;
        WOWCallback16Ex( (DWORD)selfloadheader->LoadAppSeg, WCB16_PASCAL, sizeof(args), args, &ret );
        pSeg->hSeg = LOWORD(ret);
        TRACE_(dll)("Ret LoadAppSegProc: hSeg=0x%04x\n", pSeg->hSeg);
        _lclose16( hFile16 );
		setWOW32Reserved(oldstack);

        pSeg->flags |= NE_SEGFLAGS_LOADED;
        return TRUE;
    }
    else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED))
    {
        void *mem = GlobalLock16(pSeg->hSeg);
        if (!NE_READ_DATA( pModule, mem, pos, size ))
            return FALSE;
        pos += size;
    }
    else
    {
        /*
          The following bit of code for "iterated segments" was written without
          any documentation on the format of these segments. It seems to work,
          but may be missing something.
        */
        const char *buff = NE_GET_DATA( pModule, pos, size );
        const char* curr = buff;
        char *mem = GlobalLock16(pSeg->hSeg);

        pos += size;
        if (buff == NULL) return FALSE;

        while(curr < buff + size) {
            unsigned int rept = ((const short *)curr)[0];
            unsigned int len =  ((const short *)curr)[1];

            curr += 2*sizeof(short);
            while (rept--)
            {
                memcpy( mem, curr, len );
                mem += len;
            }
            curr += len;
        }
    }

    pSeg->flags |= NE_SEGFLAGS_LOADED;

    /* Perform exported function prolog fixups */
    NE_FixupSegmentPrologs( pModule, segnum );

    if (!(pSeg->flags & NE_SEGFLAGS_RELOC_DATA))
        return TRUE;  /* No relocation data, we are done */

    if (!NE_READ_DATA( pModule, &count, pos, sizeof(count) ) || !count) return TRUE;
    pos += sizeof(count);

    TRACE("Fixups for %.*s, segment %d, hSeg %04x\n",
          *((BYTE *)pModule + pModule->ne_restab),
          (char *)pModule + pModule->ne_restab + 1,
          segnum, pSeg->hSeg );

    if (!(rep = NE_GET_DATA( pModule, pos, count * sizeof(struct relocation_entry_s) )))
        return FALSE;

    return apply_relocations( pModule, rep, count, segnum );
}