1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00
upx/src/linker.h
Markus F.X.J. Oberhumer 3d91ab6c31 Introduced bele_policy.h.
2006-08-13 15:30:26 +02:00

314 lines
8.5 KiB
C++

/* linker.h --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
markus@oberhumer.com ml1050@users.sourceforge.net
*/
#ifndef __UPX_LINKER_H
#define __UPX_LINKER_H
/*************************************************************************
//
**************************************************************************/
class Linker
{
protected:
Linker() : frozen(false) { }
public:
virtual ~Linker() { }
// endian abstraction
virtual unsigned get32(const void *b) const = 0;
virtual void set32(void *b, unsigned v) const = 0;
//
virtual bool isFrozen() const { return frozen; }
//
virtual void init(const void *pdata, int plen, int pinfo) = 0;
virtual void setLoaderAlignOffset(int phase) = 0;
virtual int addSection(const char *sname) = 0;
virtual void addSection(const char *sname, const void *sdata, int slen, int align) = 0;
virtual void freeze() = 0;
virtual int getSection(const char *sname, int *slen=NULL) = 0;
virtual unsigned char *getLoader(int *llen=NULL) = 0;
// for ElfLinker descendants
virtual void defineSymbol(const char *, unsigned) {}
virtual void relocate() {}
virtual unsigned getSymbolOffset(const char *) const { return 0; }
protected:
bool frozen;
private:
// disable copy and assignment
Linker(const Linker &); // {}
Linker& operator= (const Linker &); // { return *this; }
};
/*************************************************************************
// DefaultLinker
**************************************************************************/
class DefaultLinker : public Linker
{
protected:
DefaultLinker();
public:
virtual ~DefaultLinker();
//
virtual void init(const void *pdata, int plen, int pinfo);
virtual void setLoaderAlignOffset(int phase);
virtual int addSection(const char *sname);
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
virtual void freeze();
virtual int getSection(const char *sname, int *slen=NULL);
virtual unsigned char *getLoader(int *llen=NULL);
private:
struct Label;
struct Jump;
struct Section;
unsigned char *iloader, *oloader;
int ilen, olen;
int info;
Jump *jumps;
int njumps;
Section *sections;
int nsections;
int align_hack;
int align_offset;
};
template <class T>
struct TDefaultLinker : public DefaultLinker
{
virtual unsigned get32(const void *b) const { return T::get32(b); }
virtual void set32(void *b, unsigned v) const { T::set32(b, v); }
};
typedef TDefaultLinker<N_BELE_CTP::BEPolicy> DefaultBELinker;
typedef TDefaultLinker<N_BELE_CTP::LEPolicy> DefaultLELinker;
/*************************************************************************
// SimpleLinker
**************************************************************************/
class SimpleLinker : public Linker
{
protected:
SimpleLinker();
public:
virtual ~SimpleLinker();
//
virtual void init(const void *pdata, int plen, int pinfo);
virtual void setLoaderAlignOffset(int phase);
virtual int addSection(const char *sname);
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
virtual void freeze();
virtual int getSection(const char *sname, int *slen=NULL);
virtual unsigned char *getLoader(int *llen=NULL);
private:
unsigned char *oloader;
int olen;
};
template <class T>
struct TSimpleLinker : public SimpleLinker
{
virtual unsigned get32(const void *b) const { return T::get32(b); }
virtual void set32(void *b, unsigned v) const { T::set32(b, v); }
};
typedef TSimpleLinker<N_BELE_CTP::BEPolicy> SimpleBELinker;
typedef TSimpleLinker<N_BELE_CTP::LEPolicy> SimpleLELinker;
/*************************************************************************
// ElfLinker
**************************************************************************/
class ElfLinker : public Linker, private nocopy
{
typedef Linker super;
protected:
struct Section;
struct Symbol;
struct Relocation;
upx_byte *input;
int inputlen;
upx_byte *output;
int outputlen;
Section *head;
Section *tail;
Section **sections;
Symbol **symbols;
Relocation **relocations;
unsigned nsections;
unsigned nsymbols;
unsigned nrelocations;
void preprocessSections(char *start, const char *end);
void preprocessSymbols(char *start, const char *end);
void preprocessRelocations(char *start, const char *end);
Section *findSection(const char *name);
Symbol *findSymbol(const char *name);
void addSymbol(const char *name, const char *section, unsigned offset);
void addRelocation(const char *section, unsigned off, const char *type,
const char *symbol, unsigned add);
public:
ElfLinker();
protected:
virtual ~ElfLinker();
virtual void init(const void *pdata, int plen, int);
virtual void setLoaderAlignOffset(int phase);
virtual int addSection(const char *sname);
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
virtual void freeze();
virtual int getSection(const char *sname, int *slen=NULL);
virtual upx_byte *getLoader(int *llen=NULL);
virtual void relocate();
virtual void defineSymbol(const char *name, unsigned value);
virtual unsigned getSymbolOffset(const char *) const;
virtual unsigned get32(const void *) const { return 0; }
virtual void set32(void *, unsigned) const {}
//
void alignWithByte(unsigned len, upx_byte b);
virtual void align(unsigned len);
virtual void relocate1(Relocation *, upx_byte *location,
unsigned value, const char *type);
};
struct ElfLinker::Section : private nocopy
{
char *name;
void *input;
upx_byte *output;
unsigned size;
unsigned offset;
unsigned char align; // log2
Section *next;
Section(const char *n, const void *i, unsigned s, unsigned a=0);
~Section();
};
struct ElfLinker::Symbol : private nocopy
{
char *name;
Section *section;
unsigned offset;
Symbol(const char *n, Section *s, unsigned o);
~Symbol();
};
struct ElfLinker::Relocation : private nocopy
{
Section *section;
unsigned offset;
const char *type;
Symbol *value;
unsigned add; // used in .rela relocations
Relocation(Section *s, unsigned o, const char *t,
Symbol *v, unsigned a);
};
class ElfLinkerX86 : public ElfLinker
{
typedef ElfLinker super;
protected:
virtual void align(unsigned len);
virtual void relocate1(Relocation *, upx_byte *location,
unsigned value, const char *type);
};
class ElfLinkerAMD64 : public ElfLinker
{
typedef ElfLinker super;
protected:
virtual void align(unsigned len);
virtual void relocate1(Relocation *, upx_byte *location,
unsigned value, const char *type);
};
class ElfLinkerPpc32 : public ElfLinker
{
typedef ElfLinker super;
protected:
virtual void align(unsigned len);
virtual void relocate1(Relocation *, upx_byte *location,
unsigned value, const char *type);
};
class ElfLinkerArmLE : public ElfLinker
{
typedef ElfLinker super;
protected:
virtual void relocate1(Relocation *, upx_byte *location,
unsigned value, const char *type);
};
class ElfLinkerArmBE : public ElfLinker
{
typedef ElfLinker super;
protected:
virtual void relocate1(Relocation *, upx_byte *location,
unsigned value, const char *type);
};
#endif /* already included */
/*
vi:ts=4:et
*/