1 /* linker.h -- 2 3 This file is part of the UPX executable compressor. 4 5 Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer 6 Copyright (C) 1996-2020 Laszlo Molnar 7 All Rights Reserved. 8 9 UPX and the UCL library are free software; you can redistribute them 10 and/or modify them under the terms of the GNU General Public License as 11 published by the Free Software Foundation; either version 2 of 12 the License, or (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; see the file COPYING. 21 If not, write to the Free Software Foundation, Inc., 22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 24 Markus F.X.J. Oberhumer Laszlo Molnar 25 <markus@oberhumer.com> <ezerotven+github@gmail.com> 26 */ 27 28 #ifndef __UPX_LINKER_H 29 #define __UPX_LINKER_H 1 30 31 /************************************************************************* 32 // ElfLinker 33 **************************************************************************/ 34 35 class ElfLinker : private noncopyable { 36 friend class Packer; 37 38 public: 39 const N_BELE_RTP::AbstractPolicy *bele; // target endianness 40 protected: 41 struct Section; 42 struct Symbol; 43 struct Relocation; 44 45 upx_byte *input; 46 int inputlen; 47 upx_byte *output; 48 int outputlen; 49 50 Section *head; 51 Section *tail; 52 53 Section **sections; 54 Symbol **symbols; 55 Relocation **relocations; 56 57 unsigned nsections; 58 unsigned nsections_capacity; 59 unsigned nsymbols; 60 unsigned nsymbols_capacity; 61 unsigned nrelocations; 62 unsigned nrelocations_capacity; 63 64 bool reloc_done; 65 66 protected: 67 void preprocessSections(char *start, char *end); 68 void preprocessSymbols(char *start, char *end); 69 void preprocessRelocations(char *start, char *end); 70 Section *findSection(const char *name, bool fatal = true) const; 71 Symbol *findSymbol(const char *name, bool fatal = true) const; 72 73 Symbol *addSymbol(const char *name, const char *section, upx_uint64_t offset); 74 Relocation *addRelocation(const char *section, unsigned off, const char *type, 75 const char *symbol, upx_uint64_t add); 76 77 public: 78 ElfLinker(); 79 virtual ~ElfLinker(); 80 81 virtual void init(const void *pdata, int plen); 82 // virtual void setLoaderAlignOffset(int phase); 83 virtual int addLoader(const char *sname); 84 void addLoader(const char *s, va_list ap); 85 #if 1 && (ACC_CC_CLANG || (ACC_CC_GNUC >= 0x040100)) 86 void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__)); 87 #else 88 void __acc_cdecl_va addLoaderVA(const char *s, ...); 89 #endif 90 virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); 91 virtual int getSection(const char *sname, int *slen = NULL) const; 92 virtual int getSectionSize(const char *sname) const; 93 virtual upx_byte *getLoader(int *llen = NULL) const; 94 virtual void defineSymbol(const char *name, upx_uint64_t value); 95 virtual upx_uint64_t getSymbolOffset(const char *) const; 96 97 virtual void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const; 98 virtual void dumpSymbols(unsigned flags = 0, FILE *fp = NULL) const; 99 100 void alignWithByte(unsigned len, unsigned char b); alignCode(unsigned len)101 virtual void alignCode(unsigned len) { alignWithByte(len, 0); } alignData(unsigned len)102 virtual void alignData(unsigned len) { alignWithByte(len, 0); } 103 104 protected: 105 virtual void relocate(); 106 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 107 const char *type); 108 109 // target endianness abstraction get_te16(const void * p)110 unsigned get_te16(const void *p) const { return bele->get16(p); } get_te32(const void * p)111 unsigned get_te32(const void *p) const { return bele->get32(p); } get_te64(const void * p)112 upx_uint64_t get_te64(const void *p) const { return bele->get64(p); } set_te16(void * p,unsigned v)113 void set_te16(void *p, unsigned v) const { bele->set16(p, v); } set_te32(void * p,unsigned v)114 void set_te32(void *p, unsigned v) const { bele->set32(p, v); } set_te64(void * p,upx_uint64_t v)115 void set_te64(void *p, upx_uint64_t v) const { bele->set64(p, v); } 116 }; 117 118 struct ElfLinker::Section : private noncopyable { 119 char *name; 120 void *input; 121 upx_byte *output; 122 unsigned size; 123 upx_uint64_t offset; 124 unsigned p2align; // log2 125 Section *next; 126 127 Section(const char *n, const void *i, unsigned s, unsigned a = 0); 128 ~Section(); 129 }; 130 131 struct ElfLinker::Symbol : private noncopyable { 132 char *name; 133 Section *section; 134 upx_uint64_t offset; 135 136 Symbol(const char *n, Section *s, upx_uint64_t o); 137 ~Symbol(); 138 }; 139 140 struct ElfLinker::Relocation : private noncopyable { 141 const Section *section; 142 unsigned offset; 143 const char *type; 144 const Symbol *value; 145 upx_uint64_t add; // used in .rela relocations 146 147 Relocation(const Section *s, unsigned o, const char *t, const Symbol *v, upx_uint64_t a); 148 }; 149 150 /************************************************************************* 151 // ElfLinker arch subclasses 152 **************************************************************************/ 153 154 class ElfLinkerAMD64 : public ElfLinker { 155 typedef ElfLinker super; 156 157 protected: alignCode(unsigned len)158 virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); } 159 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 160 const char *type); 161 }; 162 163 class ElfLinkerARM64 : public ElfLinker { 164 typedef ElfLinker super; 165 166 protected: alignCode(unsigned len)167 virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); } 168 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 169 const char *type); 170 }; 171 172 class ElfLinkerArmBE : public ElfLinker { 173 typedef ElfLinker super; 174 175 public: ElfLinkerArmBE()176 ElfLinkerArmBE() { bele = &N_BELE_RTP::be_policy; } 177 178 protected: 179 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 180 const char *type); 181 }; 182 183 class ElfLinkerArmLE : public ElfLinker { 184 typedef ElfLinker super; 185 186 protected: 187 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 188 const char *type); 189 }; 190 191 class ElfLinkerArm64LE : public ElfLinker { 192 typedef ElfLinker super; 193 194 protected: 195 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 196 const char *type); 197 }; 198 199 class ElfLinkerM68k : public ElfLinker { 200 typedef ElfLinker super; 201 202 public: ElfLinkerM68k()203 ElfLinkerM68k() { bele = &N_BELE_RTP::be_policy; } 204 205 protected: 206 virtual void alignCode(unsigned len); 207 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 208 const char *type); 209 }; 210 211 class ElfLinkerMipsBE : public ElfLinker { 212 typedef ElfLinker super; 213 214 public: ElfLinkerMipsBE()215 ElfLinkerMipsBE() { bele = &N_BELE_RTP::be_policy; } 216 217 protected: 218 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 219 const char *type); 220 }; 221 222 class ElfLinkerMipsLE : public ElfLinker { 223 typedef ElfLinker super; 224 225 protected: 226 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 227 const char *type); 228 }; 229 230 class ElfLinkerPpc32 : public ElfLinker { 231 typedef ElfLinker super; 232 233 public: ElfLinkerPpc32()234 ElfLinkerPpc32() { bele = &N_BELE_RTP::be_policy; } 235 236 protected: 237 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 238 const char *type); 239 }; 240 241 class ElfLinkerPpc64le : public ElfLinker { 242 typedef ElfLinker super; 243 244 protected: 245 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 246 const char *type); 247 }; 248 249 class ElfLinkerPpc64 : public ElfLinker { 250 typedef ElfLinker super; 251 252 public: ElfLinkerPpc64()253 ElfLinkerPpc64() { bele = &N_BELE_RTP::be_policy; } 254 255 protected: 256 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 257 const char *type); 258 }; 259 260 class ElfLinkerX86 : public ElfLinker { 261 typedef ElfLinker super; 262 263 protected: alignCode(unsigned len)264 virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); } 265 virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, 266 const char *type); 267 }; 268 269 #endif /* already included */ 270 271 /* vim:set ts=4 sw=4 et: */ 272