ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
erl.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/fcntl.h>
#include <sys/unistd.h>
#include <erl.h>
#include <hashtab.h>
#include <recycle.h>
#include <tamtypes.h>
#include <kernel.h>
+ Include dependency graph for erl.c:

Go to the source code of this file.

Data Structures

struct  elf_header_t
 
struct  elf_section_t
 
struct  elf_symbol_t
 
struct  elf_reloc_t
 
struct  loosy_t
 
struct  dependancy_t
 

Macros

#define DEBUG   1
 
#define STANDALONE   1
 
#define FORCE_ALIGN   1
 
#define dprintf(a...)
 
#define rprintf(a...)
 
#define REL_TYPE   1
 
#define PROGBITS   1
 
#define NOBITS   8
 
#define REL   9
 
#define GLOBAL   1
 
#define WEAK   2
 
#define NOTYPE   0
 
#define OBJECT   1
 
#define FUNC   2
 
#define SECTION   3
 
#define R_MIPS_32   2
 
#define R_MIPS_26   4
 
#define R_MIPS_HI16   5
 
#define R_MIPS_LO16   6
 
#define free_and_return(code)
 
#define O_BINARY   0
 

Typedefs

typedef int(* func_t) (void)
 
typedef int(* start_t) (int argc, char **argv)
 

Functions

static u32 align (u32 x, int align)
 
static struct loosy_tcreate_loosy (struct erl_record_t *erl, u8 *reloc, int type)
 
static void destroy_loosy (struct loosy_t *l)
 
static void r_destroy_loosy (struct loosy_t *l)
 
static struct symbol_tcreate_symbol (struct erl_record_t *provider, u32 address)
 
static void destroy_symbol (struct symbol_t *s)
 
static struct erl_record_tallocate_erl_record ()
 
static void destroy_erl_record (struct erl_record_t *erl)
 
static int apply_reloc (u8 *reloc, int type, u32 addr)
 
struct symbol_terl_find_local_symbol (const char *symbol, struct erl_record_t *erl)
 
static struct symbol_tr_find_symbol (const char *symbol, struct erl_record_t *erl)
 
struct symbol_terl_find_symbol (const char *symbol)
 
static struct dependancy_tadd_dependancy (struct erl_record_t *depender, struct erl_record_t *provider)
 
static void destroy_dependancy (struct dependancy_t *d)
 
static void r_destroy_dependancy_r (struct erl_record_t *erl, struct dependancy_t *d)
 
static void destroy_dependancy_r (struct erl_record_t *erl)
 
static void add_loosy (struct erl_record_t *erl, u8 *reloc, int type, const char *symbol)
 
static int fix_loosy (struct erl_record_t *provider, const char *symbol, u32 address)
 
static int is_local (const char *symbol)
 
static int add_symbol (struct erl_record_t *erl, const char *symbol, u32 address)
 
int erl_add_global_symbol (const char *symbol, u32 address)
 
static int read_erl (int elf_handle, u8 *elf_mem, u32 addr, struct erl_record_t **p_erl_record)
 
static struct erl_record_t_init_load_erl_wrapper_from_file (char *erl_id)
 
static struct erl_record_tload_erl (const char *fname, u8 *elf_mem, u32 addr, int argc, char **argv)
 
struct erl_record_t_init_load_erl_from_file (const char *fname, char *erl_id)
 
struct erl_record_tload_erl_from_file (const char *fname, int argc, char **argv)
 
struct erl_record_tload_erl_from_mem (u8 *mem, int argc, char **argv)
 
struct erl_record_tload_erl_from_mem_to_addr (u8 *mem, u32 addr, int argc, char **argv)
 
struct erl_record_tload_erl_from_file_to_addr (const char *fname, u32 addr, int argc, char **argv)
 
struct erl_record_t_init_load_erl_from_file_to_addr (const char *fname, u32 addr, char *erl_id)
 
void r_unload_dependancies (char **d)
 
int unload_erl (struct erl_record_t *erl)
 
struct erl_record_terl_resolve (u32 address)
 
struct erl_record_tfind_erl (const char *name)
 
void erl_flush_symbols (struct erl_record_t *erl)
 

Variables

static const char * local_names []
 
static struct erl_record_terl_record_root = 0
 
static htabglobal_symbols = 0
 
static htabloosy_relocs = 0
 
char _init_erl_prefix [256] = ""
 
static struct dependancy_tdependancy_root = 0
 
static rerootsymbol_recycle = 0
 
erl_loader_t _init_load_erl = _init_load_erl_wrapper_from_file
 

Detailed Description

The relocatable elf loader/linker.

Definition in file erl.c.

Macro Definition Documentation

◆ DEBUG

#define DEBUG   1

Definition at line 16 of file erl.c.

◆ dprintf

#define dprintf (   a...)

Definition at line 33 of file erl.c.

◆ FORCE_ALIGN

#define FORCE_ALIGN   1

Definition at line 18 of file erl.c.

◆ free_and_return

#define free_and_return (   code)
Value:
if (!elf_mem) { \
if (names) free(names); \
if (strtab_names) free(strtab_names); \
if (sec) free(sec); \
if (sym) free(sym); \
if ((code < 0) && erl_record) destroy_erl_record(erl_record); \
} \
return code
static void destroy_erl_record(struct erl_record_t *erl)
Definition: erl.c:368

◆ FUNC

#define FUNC   2

Definition at line 195 of file erl.c.

◆ GLOBAL

#define GLOBAL   1

Definition at line 191 of file erl.c.

◆ NOBITS

#define NOBITS   8

Definition at line 189 of file erl.c.

◆ NOTYPE

#define NOTYPE   0

Definition at line 193 of file erl.c.

◆ O_BINARY

#define O_BINARY   0

Definition at line 925 of file erl.c.

◆ OBJECT

#define OBJECT   1

Definition at line 194 of file erl.c.

◆ PROGBITS

#define PROGBITS   1

Definition at line 188 of file erl.c.

◆ R_MIPS_26

#define R_MIPS_26   4

Definition at line 198 of file erl.c.

◆ R_MIPS_32

#define R_MIPS_32   2

Definition at line 197 of file erl.c.

◆ R_MIPS_HI16

#define R_MIPS_HI16   5

Definition at line 199 of file erl.c.

◆ R_MIPS_LO16

#define R_MIPS_LO16   6

Definition at line 200 of file erl.c.

◆ REL

#define REL   9

Definition at line 190 of file erl.c.

◆ REL_TYPE

#define REL_TYPE   1

Definition at line 187 of file erl.c.

◆ rprintf

#define rprintf (   a...)

Definition at line 34 of file erl.c.

◆ SECTION

#define SECTION   3

Definition at line 196 of file erl.c.

◆ STANDALONE

#define STANDALONE   1

Definition at line 17 of file erl.c.

◆ WEAK

#define WEAK   2

Definition at line 192 of file erl.c.

Typedef Documentation

◆ func_t

typedef int(* func_t) (void)

Definition at line 928 of file erl.c.

◆ start_t

typedef int(* start_t) (int argc, char **argv)

Definition at line 929 of file erl.c.

Function Documentation

◆ _init_load_erl_from_file()

struct erl_record_t* _init_load_erl_from_file ( const char *  fname,
char *  erl_id 
)

Definition at line 1012 of file erl.c.

1012  {
1013  char tfname[1024];
1014  struct erl_record_t * r;
1015  char * argv[2];
1016 
1017  if (erl_id)
1018  if ((r = find_erl(erl_id)))
1019  return r;
1020 
1021  argv[0] = erl_id;
1022  argv[1] = 0;
1023 
1024  strcpy(tfname, _init_erl_prefix);
1025  strcat(tfname, fname);
1026 
1027  return load_erl_from_file(tfname, 1, argv);
1028 }
char * erl_id
Definition: erl-support.c:15
struct erl_record_t * load_erl_from_file(const char *fname, int argc, char **argv)
Definition: erl.c:1030
struct erl_record_t * find_erl(const char *name)
Definition: erl.c:1133
char _init_erl_prefix[256]
Definition: erl.c:281

References _init_erl_prefix, erl_id, find_erl(), and load_erl_from_file().

Referenced by _init_load_erl_wrapper_from_file(), and main().

◆ _init_load_erl_from_file_to_addr()

struct erl_record_t* _init_load_erl_from_file_to_addr ( const char *  fname,
u32  addr,
char *  erl_id 
)

Definition at line 1055 of file erl.c.

1055  {
1056  char tfname[1024];
1057  struct erl_record_t * r;
1058  char * argv[2];
1059 
1060  if (erl_id)
1061  if ((r = find_erl(erl_id)))
1062  return r;
1063 
1064  argv[0] = erl_id;
1065  argv[1] = 0;
1066 
1067  strcpy(tfname, _init_erl_prefix);
1068  strcat(tfname, fname);
1069 
1070  return load_erl_from_file_to_addr(tfname, addr, 1, argv);
1071 }
struct erl_record_t * load_erl_from_file_to_addr(const char *fname, u32 addr, int argc, char **argv)
Definition: erl.c:1048

References _init_erl_prefix, erl_id, find_erl(), and load_erl_from_file_to_addr().

◆ _init_load_erl_wrapper_from_file()

static struct erl_record_t* _init_load_erl_wrapper_from_file ( char *  erl_id)
static

Definition at line 931 of file erl.c.

931  {
932  char tmpnam[256];
933  strcpy(tmpnam, erl_id);
934  strcat(tmpnam, ".erl");
935  return _init_load_erl_from_file(tmpnam, erl_id);
936 }
struct erl_record_t * _init_load_erl_from_file(const char *fname, char *erl_id)
Definition: erl.c:1012

References _init_load_erl_from_file(), and erl_id.

◆ add_dependancy()

static struct dependancy_t* add_dependancy ( struct erl_record_t depender,
struct erl_record_t provider 
)
static

Definition at line 450 of file erl.c.

450  {
451  struct dependancy_t * d;
452 
453  if (depender == provider)
454  return 0;
455 
456  if (!(d = (struct dependancy_t *) malloc(sizeof(struct dependancy_t))))
457  return 0;
458 
459  d->depender = depender;
460  d->provider = provider;
461 
462  if ((d->next = dependancy_root))
463  d->next->prev = d;
464 
465  d->prev = 0;
466  dependancy_root = d;
467 
468  return d;
469 }
static struct dependancy_t * dependancy_root
Definition: erl.c:283
struct erl_record_t * provider
Definition: erl.c:270
struct dependancy_t * next
Definition: erl.c:271
struct erl_record_t * depender
Definition: erl.c:270
struct dependancy_t * prev
Definition: erl.c:271

References dependancy_root, dependancy_t::depender, dependancy_t::next, dependancy_t::prev, and dependancy_t::provider.

Referenced by fix_loosy(), and read_erl().

◆ add_loosy()

static void add_loosy ( struct erl_record_t erl,
u8 reloc,
int  type,
const char *  symbol 
)
static

Definition at line 499 of file erl.c.

499  {
500  struct loosy_t * l;
501 
502  l = create_loosy(erl, reloc, type);
503 
504  if (!loosy_relocs)
505  loosy_relocs = hcreate(6);
506 
507  if (!hadd(loosy_relocs, symbol, strlen(symbol), l)) {
508  l->next = hstuff(loosy_relocs);
509  hstuff(loosy_relocs) = l;
510  } else {
511  hkey(loosy_relocs) = (ub1 *)strdup(symbol);
512  }
513 }
static struct loosy_t * create_loosy(struct erl_record_t *erl, u8 *reloc, int type)
Definition: erl.c:302
static htab * loosy_relocs
Definition: erl.c:279
#define hkey(t)
Definition: hashtab.h:109
#define hstuff(t)
Definition: hashtab.h:111
htab * hcreate()
word hadd()
u8 ub1
Definition: standard.h:36
Definition: erl.c:262
u8 * reloc
Definition: erl.c:263
int type
Definition: erl.c:264
struct loosy_t * next
Definition: erl.c:265
struct erl_record_t * erl
Definition: erl.c:266

References create_loosy(), loosy_t::erl, hadd(), hcreate(), hkey, hstuff, loosy_relocs, loosy_t::next, loosy_t::reloc, and loosy_t::type.

Referenced by read_erl().

◆ add_symbol()

static int add_symbol ( struct erl_record_t erl,
const char *  symbol,
u32  address 
)
static

Definition at line 546 of file erl.c.

546  {
547  htab * symbols;
548 
549  if (erl) {
550  symbols = erl->symbols;
551  } else {
552  if (!global_symbols)
553  global_symbols = hcreate(6);
554  symbols = global_symbols;
555  }
556 
557  if (!is_local(symbol) && erl_find_symbol(symbol))
558  return -1;
559 
560  dprintf("Adding symbol %s at address %08X\n", symbol, address);
561 
562  if (fix_loosy(erl, symbol, address)) {
563 #ifdef _EE
564  FlushCache(2);
565  FlushCache(0);
566 #endif
567  }
568 
569  hadd(symbols, strdup(symbol), strlen(symbol), create_symbol(erl, address));
570 
571  return 0;
572 }
static htab * global_symbols
Definition: erl.c:278
static struct symbol_t * create_symbol(struct erl_record_t *provider, u32 address)
Definition: erl.c:331
struct symbol_t * erl_find_symbol(const char *symbol)
Definition: erl.c:443
static int is_local(const char *symbol)
Definition: erl.c:536
#define dprintf(a...)
Definition: erl.c:33
static int fix_loosy(struct erl_record_t *provider, const char *symbol, u32 address)
Definition: erl.c:515
void FlushCache(s32 operation)
struct htab * symbols
Definition: erl.h:38
Definition: hashtab.h:56

References create_symbol(), dprintf, loosy_t::erl, erl_find_symbol(), fix_loosy(), FlushCache(), global_symbols, hadd(), hcreate(), is_local(), and erl_loader_t::symbols.

Referenced by erl_add_global_symbol(), and read_erl().

◆ align()

static u32 align ( u32  x,
int  align 
)
static

Definition at line 286 of file erl.c.

286  {
287 #ifdef FORCE_ALIGN
288  if (align < 16)
289  align = 16;
290 #endif
291 
292  align--;
293 
294  if (x & align) {
295  x |= align;
296  x++;
297  }
298 
299  return x;
300 }
static u32 align(u32 x, int align)
Definition: erl.c:286
s32 x
Definition: libmouse.c:34

References x.

Referenced by read_erl().

◆ allocate_erl_record()

static struct erl_record_t* allocate_erl_record ( )
static

Definition at line 349 of file erl.c.

349  {
350  struct erl_record_t * r;
351 
352  if (!(r = (struct erl_record_t *) malloc(sizeof(struct erl_record_t))))
353  return 0;
354 
355  r->bytes = NULL;
356  r->symbols = hcreate(6);
357 
358  if ((r->next = erl_record_root))
359  r->next->prev = r;
360  r->prev = 0;
361  erl_record_root = r;
362 
363  r->flags = 0;
364 
365  return r;
366 }
static struct erl_record_t * erl_record_root
Definition: erl.c:276
u32 flags
Definition: erl.h:35
struct erl_record_t * next
Definition: erl.h:39
struct erl_record_t * prev
Definition: erl.h:39
u8 * bytes
Definition: erl.h:31
#define NULL
Definition: tamtypes.h:91

References erl_loader_t::bytes, erl_record_root, erl_loader_t::flags, hcreate(), erl_loader_t::next, NULL, erl_loader_t::prev, and erl_loader_t::symbols.

Referenced by read_erl().

◆ apply_reloc()

static int apply_reloc ( u8 reloc,
int  type,
u32  addr 
)
static

Definition at line 392 of file erl.c.

392  {
393  u32 u_current_data;
394  s32 s_current_data;
395  u32 newstate;
396 
397  if (((u32)reloc)&0x3)
398  {
399  printf("Unaligned reloc (%p) type=%d!\n", reloc, type);
400  }
401  memcpy(&u_current_data, reloc, 4);
402  memcpy(&s_current_data, reloc, 4);
403 
404  switch (type) {
405  case R_MIPS_32:
406  newstate = s_current_data + addr;
407  break;
408  case R_MIPS_26:
409  newstate = (u_current_data & 0xfc000000) | (((u_current_data & 0x03ffffff) + (addr >> 2)) & 0x3ffffff);
410  break;
411  case R_MIPS_HI16:
412  newstate = (u_current_data & 0xffff0000) | ((((s_current_data << 16) >> 16) + (addr >> 16) + ((addr & 0xffff) >= 0x8000 ? 1 : 0)) & 0xffff);
413  break;
414  case R_MIPS_LO16:
415  newstate = (u_current_data & 0xffff0000) | ((((s_current_data << 16) >> 16) + (addr & 0xffff)) & 0xffff);
416  break;
417  default:
418  return -1;
419  }
420 
421  memcpy(reloc, &newstate, 4);
422 
423  dprintf("Changed data at %08X from %08X to %08X.\n", reloc, u_current_data, newstate);
424  return 0;
425 }
#define R_MIPS_26
Definition: erl.c:198
#define R_MIPS_32
Definition: erl.c:197
#define R_MIPS_HI16
Definition: erl.c:199
#define R_MIPS_LO16
Definition: erl.c:200
signed int s32
Definition: tamtypes.h:58
unsigned int u32
Definition: tamtypes.h:30

References dprintf, R_MIPS_26, R_MIPS_32, R_MIPS_HI16, and R_MIPS_LO16.

Referenced by fix_loosy(), and read_erl().

◆ create_loosy()

static struct loosy_t* create_loosy ( struct erl_record_t erl,
u8 reloc,
int  type 
)
static

Definition at line 302 of file erl.c.

302  {
303  struct loosy_t * r;
304 
305  if (!(r = (struct loosy_t *) malloc(sizeof(struct loosy_t))))
306  return 0;
307 
308  r->reloc = reloc;
309  r->type = type;
310  r->next = 0;
311  r->erl = erl;
312 
313  return r;
314 }

References loosy_t::erl, loosy_t::next, loosy_t::reloc, and loosy_t::type.

Referenced by add_loosy().

◆ create_symbol()

static struct symbol_t* create_symbol ( struct erl_record_t provider,
u32  address 
)
static

Definition at line 331 of file erl.c.

331  {
332  struct symbol_t * r;
333 
334  if (!symbol_recycle)
335  symbol_recycle = remkroot(sizeof(struct symbol_t));
336 
337  r = (struct symbol_t *) renew(symbol_recycle);
338 
339  r->provider = provider;
340  r->address = address;
341 
342  return r;
343 }
static reroot * symbol_recycle
Definition: erl.c:329
#define renew(r)
Definition: recycle.h:53
reroot * remkroot()
Definition: erl.h:42
u32 address
Definition: erl.h:44
struct erl_record_t * provider
Definition: erl.h:43

References symbol_t::address, symbol_t::provider, remkroot(), renew, and symbol_recycle.

Referenced by add_symbol().

◆ destroy_dependancy()

static void destroy_dependancy ( struct dependancy_t d)
static

Definition at line 471 of file erl.c.

471  {
472  if (d->prev)
473  d->prev->next = d->next;
474  else
475  dependancy_root = d->next;
476 
477  if (d->next)
478  d->next->prev = d->prev;
479 
480  free(d);
481 }

References dependancy_root, dependancy_t::next, and dependancy_t::prev.

Referenced by r_destroy_dependancy_r().

◆ destroy_dependancy_r()

static void destroy_dependancy_r ( struct erl_record_t erl)
static

Definition at line 495 of file erl.c.

495  {
497 }
static void r_destroy_dependancy_r(struct erl_record_t *erl, struct dependancy_t *d)
Definition: erl.c:483

References dependancy_root, and r_destroy_dependancy_r().

Referenced by unload_erl().

◆ destroy_erl_record()

static void destroy_erl_record ( struct erl_record_t erl)
static

Definition at line 368 of file erl.c.

368  {
369  if (!erl)
370  return;
371 
372  if (erl->bytes) {
373  if (erl->flags & ERL_FLAG_CLEAR)
374  memset(erl->bytes, 0, erl->fullsize);
375  if (!(erl->flags & ERL_FLAG_STATIC))
376  free(erl->bytes);
377  }
378 
379  erl_flush_symbols(erl);
380 
381  if (erl->prev)
382  erl->prev->next = erl->next;
383  else
384  erl_record_root = erl->next;
385 
386  if (erl->next)
387  erl->next->prev = erl->prev;
388 
389  free(erl);
390 }
void erl_flush_symbols(struct erl_record_t *erl)
Definition: erl.c:1145
#define ERL_FLAG_CLEAR
Definition: erl.h:28
#define ERL_FLAG_STATIC
Definition: erl.h:26
u32 fullsize
Definition: erl.h:32

References erl_loader_t::bytes, ERL_FLAG_CLEAR, ERL_FLAG_STATIC, erl_flush_symbols(), erl_record_root, erl_loader_t::flags, erl_loader_t::fullsize, erl_loader_t::next, and erl_loader_t::prev.

Referenced by unload_erl().

◆ destroy_loosy()

static void destroy_loosy ( struct loosy_t l)
static

Definition at line 316 of file erl.c.

316  {
317  free(l);
318 }

Referenced by r_destroy_loosy().

◆ destroy_symbol()

static void destroy_symbol ( struct symbol_t s)
static

Definition at line 345 of file erl.c.

345  {
347 }
s32 s
Definition: ps2ipc.c:30
#define redel(root, item)
Definition: recycle.h:60

References redel, s, and symbol_recycle.

Referenced by erl_flush_symbols().

◆ erl_add_global_symbol()

int erl_add_global_symbol ( const char *  symbol,
u32  address 
)

Definition at line 574 of file erl.c.

574  {
575  return add_symbol(0, symbol, address);
576 }
static int add_symbol(struct erl_record_t *erl, const char *symbol, u32 address)
Definition: erl.c:546

References add_symbol().

Referenced by export_symbols().

◆ erl_find_local_symbol()

struct symbol_t* erl_find_local_symbol ( const char *  symbol,
struct erl_record_t erl 
)

Definition at line 427 of file erl.c.

427  {
428  if (!erl)
429  return 0;
430  if (hfind(erl->symbols, symbol, strlen(symbol)))
431  return hstuff(erl->symbols);
432  return 0;
433 }
word hfind()

References hfind(), hstuff, and erl_loader_t::symbols.

Referenced by load_erl(), and unload_erl().

◆ erl_find_symbol()

struct symbol_t* erl_find_symbol ( const char *  symbol)

Definition at line 443 of file erl.c.

443  {
444  if (global_symbols)
445  if (hfind(global_symbols, symbol, strlen(symbol)))
446  return hstuff(global_symbols);
447  return r_find_symbol(symbol, erl_record_root);
448 }
static struct symbol_t * r_find_symbol(const char *symbol, struct erl_record_t *erl)
Definition: erl.c:435

References erl_record_root, global_symbols, hfind(), hstuff, and r_find_symbol().

Referenced by add_symbol(), main(), and read_erl().

◆ erl_flush_symbols()

void erl_flush_symbols ( struct erl_record_t erl)

Definition at line 1145 of file erl.c.

1145  {
1146  if (!erl->symbols)
1147  return;
1148 
1149  if (hfirst(erl->symbols)) do {
1150  destroy_symbol((struct symbol_t *) hstuff(erl->symbols));
1151  free(hkey(erl->symbols));
1152  hdel(erl->symbols);
1153  } while (hcount(erl->symbols));
1154 
1155  hdestroy(erl->symbols);
1156 
1157  erl->symbols = 0;
1158 }
static void destroy_symbol(struct symbol_t *s)
Definition: erl.c:345
word hfirst()
#define hcount(t)
Definition: hashtab.h:108
word hdel()
void hdestroy()

References destroy_symbol(), hcount, hdel(), hdestroy(), hfirst(), hkey, hstuff, and erl_loader_t::symbols.

Referenced by destroy_erl_record(), and unload_erl().

◆ erl_resolve()

struct erl_record_t* erl_resolve ( u32  address)

Definition at line 1121 of file erl.c.

1121  {
1122  struct erl_record_t * r;
1123 
1124  for (r = erl_record_root; r; r = r->next) {
1125  u32 r_ptr = (u32) r->bytes;
1126  if ((address >= r_ptr) && (address < (r_ptr + r->fullsize)))
1127  return r;
1128  }
1129 
1130  return 0;
1131 }

References erl_loader_t::bytes, erl_record_root, erl_loader_t::fullsize, and erl_loader_t::next.

◆ find_erl()

struct erl_record_t* find_erl ( const char *  name)

Definition at line 1133 of file erl.c.

1133  {
1134  struct erl_record_t * r;
1135 
1136  for (r = erl_record_root; r; r = r->next) {
1137  if (r->name)
1138  if (!strcmp(name, r->name))
1139  return r;
1140  }
1141 
1142  return 0;
1143 }
char * name
Definition: erl.h:33

References erl_record_root, erl_loader_t::name, and erl_loader_t::next.

Referenced by _init_load_erl_from_file(), _init_load_erl_from_file_to_addr(), and r_unload_dependancies().

◆ fix_loosy()

static int fix_loosy ( struct erl_record_t provider,
const char *  symbol,
u32  address 
)
static

Definition at line 515 of file erl.c.

515  {
516  struct loosy_t * l;
517  int count = 0;
518 
519  if (!loosy_relocs)
520  return count;
521 
522  if (hfind(loosy_relocs, symbol, strlen(symbol))) {
523  for (l = hstuff(loosy_relocs); l; l = l->next) {
524  apply_reloc(l->reloc, l->type, address);
525  add_dependancy(l->erl, provider);
526  count++;
527  }
529  free(hkey(loosy_relocs));
531  }
532 
533  return count;
534 }
static struct dependancy_t * add_dependancy(struct erl_record_t *depender, struct erl_record_t *provider)
Definition: erl.c:450
static void r_destroy_loosy(struct loosy_t *l)
Definition: erl.c:320
static int apply_reloc(u8 *reloc, int type, u32 addr)
Definition: erl.c:392

References add_dependancy(), apply_reloc(), loosy_t::erl, hdel(), hfind(), hkey, hstuff, loosy_relocs, loosy_t::next, r_destroy_loosy(), loosy_t::reloc, and loosy_t::type.

Referenced by add_symbol().

◆ is_local()

static int is_local ( const char *  symbol)
static

Definition at line 536 of file erl.c.

536  {
537  const char ** p;
538 
539  for (p = local_names; *p; p++)
540  if (!strcmp(*p, symbol))
541  return 1;
542 
543  return 0;
544 }
static const char * local_names[]
Definition: erl.c:205

References local_names.

Referenced by add_symbol().

◆ load_erl()

static struct erl_record_t* load_erl ( const char *  fname,
u8 elf_mem,
u32  addr,
int  argc,
char **  argv 
)
static

Definition at line 940 of file erl.c.

940  {
941  struct erl_record_t * r;
942  struct symbol_t * s;
943  int elf_handle = 0;
944 
945  dprintf("Reading ERL file.\n");
946 
947  if (fname) {
948  if ((elf_handle = open(fname, O_RDONLY | O_BINARY)) < 0) {
949  dprintf("Error operning erl file: %s\n", fname);
950  return 0;
951  }
952  }
953 
954  if (read_erl(elf_handle, elf_mem, addr, &r) < 0) {
955  dprintf("Error loading erl file.\n");
956  if (fname) {
957  close(elf_handle);
958  }
959  return 0;
960  }
961 
962  if (fname) {
963  close(elf_handle);
964  }
965 
966  if ((s = erl_find_local_symbol("erl_id", r))) {
967  r->name = *(char **) s->address;
968  } else {
969  r->name = 0;
970  }
971 
972  dprintf("erl_id = %08X.\n", r->name);
973 
974  if ((s = erl_find_local_symbol("erl_dependancies", r))) {
975  r->dependancies = (char **) s->address;
976  } else {
977  r->dependancies = 0;
978  }
979 
980  dprintf("erl_dependancies = %08X.\n", r->dependancies);
981 
982  if (r->dependancies) {
983  char ** d;
984  for (d = r->dependancies; *d; d++) {
985  dprintf("Loading dependancy: %s.\n", *d);
986  _init_load_erl(*d);
987  }
988  }
989 
990  if ((s = erl_find_local_symbol("_init", r))) {
991  dprintf("_init = %08X\n", s->address);
992 #ifdef _EE
993  ((func_t)s->address)();
994 #endif
995  }
996 
997  if ((s = erl_find_local_symbol("_start", r))) {
998  int _start_ret;
999  dprintf("_start = %08X\n", s->address);
1000 #ifdef _EE
1001  if ((_start_ret = ((start_t)s->address)(argc, argv))) {
1002  dprintf("Module's _start returned %i, unloading module.\n", _start_ret);
1003  if (unload_erl(r))
1004  return 0;
1005  }
1006 #endif
1007  }
1008 
1009  return r;
1010 }
int unload_erl(struct erl_record_t *erl)
Definition: erl.c:1084
#define O_BINARY
Definition: erl.c:925
struct symbol_t * erl_find_local_symbol(const char *symbol, struct erl_record_t *erl)
Definition: erl.c:427
int(* start_t)(int argc, char **argv)
Definition: erl.c:929
static int read_erl(int elf_handle, u8 *elf_mem, u32 addr, struct erl_record_t **p_erl_record)
Definition: erl.c:578
erl_loader_t _init_load_erl
Definition: erl.c:938
int(* func_t)(void)
Definition: erl.c:928
char ** dependancies
Definition: erl.h:34

References _init_load_erl, erl_loader_t::dependancies, dprintf, erl_find_local_symbol(), erl_loader_t::name, O_BINARY, read_erl(), s, and unload_erl().

Referenced by load_erl_from_file(), load_erl_from_file_to_addr(), load_erl_from_mem(), and load_erl_from_mem_to_addr().

◆ load_erl_from_file()

struct erl_record_t* load_erl_from_file ( const char *  fname,
int  argc,
char **  argv 
)

Definition at line 1030 of file erl.c.

1030  {
1031  return load_erl(fname, 0, ERL_DYN_ADDR, argc, argv);
1032 }
static struct erl_record_t * load_erl(const char *fname, u8 *elf_mem, u32 addr, int argc, char **argv)
Definition: erl.c:940
#define ERL_DYN_ADDR
Definition: erl.h:66

References ERL_DYN_ADDR, and load_erl().

Referenced by _init_load_erl_from_file().

◆ load_erl_from_file_to_addr()

struct erl_record_t* load_erl_from_file_to_addr ( const char *  fname,
u32  addr,
int  argc,
char **  argv 
)

Definition at line 1048 of file erl.c.

1048  {
1049  return load_erl(fname, 0, addr, argc, argv);
1050 }

References load_erl().

Referenced by _init_load_erl_from_file_to_addr().

◆ load_erl_from_mem()

struct erl_record_t* load_erl_from_mem ( u8 mem,
int  argc,
char **  argv 
)

Definition at line 1034 of file erl.c.

1034  {
1035  return load_erl(0, mem, ERL_DYN_ADDR, argc, argv);
1036 }

References ERL_DYN_ADDR, and load_erl().

◆ load_erl_from_mem_to_addr()

struct erl_record_t* load_erl_from_mem_to_addr ( u8 mem,
u32  addr,
int  argc,
char **  argv 
)

Definition at line 1041 of file erl.c.

1041  {
1042  return load_erl(0, mem, addr, argc, argv);
1043 }

References load_erl().

◆ r_destroy_dependancy_r()

static void r_destroy_dependancy_r ( struct erl_record_t erl,
struct dependancy_t d 
)
static

Definition at line 483 of file erl.c.

483  {
484  if (!d)
485  return;
486 
487  r_destroy_dependancy_r(erl, d->next);
488 
489  if (erl == d->depender)
491 
492  return;
493 }
static void destroy_dependancy(struct dependancy_t *d)
Definition: erl.c:471

References dependancy_t::depender, destroy_dependancy(), and dependancy_t::next.

Referenced by destroy_dependancy_r().

◆ r_destroy_loosy()

static void r_destroy_loosy ( struct loosy_t l)
static

Definition at line 320 of file erl.c.

320  {
321  if (!l)
322  return;
323 
324  r_destroy_loosy(l->next);
325 
326  destroy_loosy(l);
327 }
static void destroy_loosy(struct loosy_t *l)
Definition: erl.c:316

References destroy_loosy(), and loosy_t::next.

Referenced by fix_loosy().

◆ r_find_symbol()

static struct symbol_t* r_find_symbol ( const char *  symbol,
struct erl_record_t erl 
)
static

Definition at line 435 of file erl.c.

435  {
436  if (!erl)
437  return 0;
438  if (hfind(erl->symbols, symbol, strlen(symbol)))
439  return hstuff(erl->symbols);
440  return r_find_symbol(symbol, erl->next);
441 }

References hfind(), hstuff, erl_loader_t::next, and erl_loader_t::symbols.

Referenced by erl_find_symbol().

◆ r_unload_dependancies()

void r_unload_dependancies ( char **  d)

Definition at line 1073 of file erl.c.

1073  {
1074  struct erl_record_t * erl;
1075  if (!(*d))
1076  return;
1077 
1078  r_unload_dependancies(d + 1);
1079 
1080  if ((erl = find_erl(*d)))
1081  unload_erl(erl);
1082 }
void r_unload_dependancies(char **d)
Definition: erl.c:1073

References find_erl(), and unload_erl().

Referenced by unload_erl().

◆ read_erl()

static int read_erl ( int  elf_handle,
u8 elf_mem,
u32  addr,
struct erl_record_t **  p_erl_record 
)
static

Definition at line 578 of file erl.c.

578  {
579  struct elf_header_t head;
580  struct elf_section_t * sec = 0;
581  struct elf_symbol_t * sym = 0;
582  struct elf_reloc_t reloc;
583  int i, j;
584  // int erx_compressed; // Not used
585  char * names = 0, * strtab_names = 0, * reloc_section = 0;
586  int symtab = 0, strtab = 0, linked_strtab = 0;
587  u8 * magic;
588  u32 fullsize = 0;
589  struct erl_record_t * erl_record = 0;
590  struct symbol_t * s;
591 
592  *p_erl_record = 0;
593 
594 #define free_and_return(code) if (!elf_mem) { \
595  if (names) free(names); \
596  if (strtab_names) free(strtab_names); \
597  if (sec) free(sec); \
598  if (sym) free(sym); \
599  if ((code < 0) && erl_record) destroy_erl_record(erl_record); \
600 } \
601 return code
602 
603  if (!(erl_record = allocate_erl_record())) {
604  dprintf("Memory allocation error.\n");
605  free_and_return(-1);
606  }
607 
608  // Reading the main ELF header.
609  if (elf_mem) {
610  memcpy(&head, elf_mem, sizeof(head));
611  } else {
612  lseek(elf_handle, 0, SEEK_SET);
613  read(elf_handle, &head, sizeof(head));
614  }
615 
616  magic = head.e_ident.cook.ei_magic;
617 
618  if ((magic[0] != 0x7f) || (magic[1] != 'E') || (magic[2] != 'L') || ((magic[3] != 'F') && (magic[3] != 'X'))) {
619  dprintf("Not an ELF file.\n");
620  free_and_return(-1);
621  }
622 
623  // erx_compressed = magic[3] == 'X'; //not used
624 
625  dprintf("ELF Class : %s\n", elf_classes[head.e_ident.cook.ei_class]);
626  dprintf("Data encoding: %s\n", elf_encodings[head.e_ident.cook.ei_data]);
627  dprintf("Elf version : %i\n", head.e_ident.cook.ei_version);
628  if (head.e_type == 0xffff) {
629  dprintf("Object type : Processor specific (hi)\n");
630  } else if (head.e_type == 0xff00) {
631  dprintf("Object type : Processor specific (lo)\n");
632  } else {
633  dprintf("Object type : %s\n", elf_types[head.e_type]);
634  }
635  dprintf("Machine type : %s\n", elf_machines[head.e_machine]);
636  dprintf("Object ver. : %i\n", head.e_version);
637  dprintf("Elf entry : %08X\n", head.e_entry);
638  dprintf("PH offset : %08X\n", head.e_phoff);
639  dprintf("SH offset : %08X\n", head.e_shoff);
640  dprintf("Flags : %08X\n", head.e_flags);
641  dprintf("Header size : %04X\n", head.e_ehsize);
642  dprintf("PH ent. size : %04X\n", head.e_phentsize);
643  dprintf("PH number : %04X\n", head.e_phnum);
644  dprintf("SH ent. size : %04X\n", head.e_shentsize);
645  dprintf("SH number : %04X\n", head.e_shnum);
646  dprintf("SH str index : %04X\n", head.e_shstrndx);
647 
648  if (head.e_type != REL_TYPE) {
649  dprintf("File isn't a relocatable ELF file.\n");
650  free_and_return(-1);
651  }
652 
653  // Reading the section table.
654  if (sizeof(struct elf_section_t) != head.e_shentsize) {
655  dprintf("Inconsistancy in section table entries.\n");
656  free_and_return(-1);
657  }
658 
659  // **TODO** handle compession
660  if (elf_mem) {
661  sec = (struct elf_section_t *) (elf_mem + head.e_shoff);
662  } else {
663  if (!(sec = (struct elf_section_t *) malloc(sizeof(struct elf_section_t) * head.e_shnum))) {
664  dprintf("Not enough memory.\n");
665  free_and_return(-1);
666  }
667  lseek(elf_handle, head.e_shoff, SEEK_SET);
668  read(elf_handle, sec, sizeof(struct elf_section_t) * head.e_shnum);
669  }
670 
671  // Reading the section names's table.
672  // **TODO** handle compession
673  if (elf_mem) {
674  names = (char *) (elf_mem + sec[head.e_shstrndx].sh_offset);
675  } else {
676  if (!(names = (char *) malloc(sec[head.e_shstrndx].sh_size))) {
677  dprintf("Not enough memory.\n");
678  free_and_return(-1);
679  }
680  lseek(elf_handle, sec[head.e_shstrndx].sh_offset, SEEK_SET);
681  read(elf_handle, names, sec[head.e_shstrndx].sh_size);
682  }
683 
684 
685  // Parsing the sections, and displaying them at the same time.
686  dprintf("##: type flags offset size link info align entsize name\n");
687  for (i = 1; i < head.e_shnum; i++) {
688  if (!strcmp(names + sec[i].sh_name, ".symtab")) {
689  symtab = i;
690  linked_strtab = sec[i].sh_link;
691  } else if (!strcmp(names + sec[i].sh_name, ".strtab")) {
692  strtab = i;
693  }
694 
695  if ((sec[i].sh_type == PROGBITS) || (sec[i].sh_type == NOBITS)) {
696  // Let's use this, it's not filled for relocatable objects.
697  fullsize = align(fullsize, sec[i].sh_addralign);
698  sec[i].sh_addr = fullsize;
699  fullsize += sec[i].sh_size;
700  dprintf("Section to load at %08X:\n", sec[i].sh_addr);
701  }
702 
703  dprintf("%2i: ", i);
704  if (sec[i].sh_type <= 0xff) {
705  rprintf("%-8s ", section_types[sec[i].sh_type]);
706  } else if (sec[i].sh_type == 0x70000006) {
707  rprintf("Reginfo ");
708  } else {
709  rprintf("UNKNOW ");
710  }
711 
712  rprintf( "%3s ", section_flags[sec[i].sh_flags & 7]);
713  rprintf( "%08X ", sec[i].sh_offset);
714  rprintf( "%08X ", sec[i].sh_size);
715  rprintf( "%5i ", sec[i].sh_link);
716  rprintf( "%5i ", sec[i].sh_info);
717  rprintf( "%5i ", sec[i].sh_addralign);
718  rprintf("%5i ", sec[i].sh_entsize);
719  rprintf( "%s\n", names + sec[i].sh_name);
720  }
721 
722  if (symtab) {
723  dprintf("Discovered symtab = %i\n", symtab);
724  } else {
725  dprintf("No symbol table.\n");
726  free_and_return(-1);
727  }
728 
729  if (strtab) {
730  dprintf("Discovered strtab = %i\n", strtab);
731  } else {
732  dprintf("No string table.\n");
733  free_and_return(-1);
734  }
735 
736  if (strtab != linked_strtab) {
737  dprintf("Warning, inconsistancy: strtab != symtab.sh_link (%i != %i)\n", strtab, linked_strtab);
738  free_and_return(-1);
739  }
740 
741  if (sizeof(struct elf_symbol_t) != sec[symtab].sh_entsize) {
742  dprintf("Symbol entries not consistant.\n");
743  free_and_return(-1);
744  }
745 
746  dprintf("Computed needed size to load the erl file: %i\n", fullsize);
747 
748  // Loading progbits sections.
749  if (addr == ERL_DYN_ADDR) {
750  erl_record->bytes = (u8 *) malloc(fullsize);
751  if (!erl_record->bytes) {
752  dprintf("Cannot allocate ERL bytes.\n");
753  free_and_return(-1);
754  }
755  } else {
756  erl_record->bytes = (u8 *) addr;
757  erl_record->flags |= ERL_FLAG_STATIC;
758  }
759 
760  erl_record->fullsize = fullsize;
761  dprintf("Base address: %08X\n", erl_record->bytes);
762  for (i = 1; i < head.e_shnum; i++) {
763  switch (sec[i].sh_type) {
764  case PROGBITS:
765  // **TODO** handle compession
766  dprintf("Reading section %s at %08X.\n", names + sec[i].sh_name, erl_record->bytes + sec[i].sh_addr);
767  if (elf_mem) {
768  memcpy(erl_record->bytes + sec[i].sh_addr, elf_mem + sec[i].sh_offset, sec[i].sh_size);
769  } else {
770  lseek(elf_handle, sec[i].sh_offset, SEEK_SET);
771  read(elf_handle, erl_record->bytes + sec[i].sh_addr, sec[i].sh_size);
772  }
773  break;
774  case NOBITS:
775  dprintf("Zeroing section %s at %08X.\n", names + sec[i].sh_name, erl_record->bytes + sec[i].sh_addr);
776  memset(erl_record->bytes + sec[i].sh_addr, 0, sec[i].sh_size);
777  break;
778  }
779  }
780 
781 
782  // Loading strtab.
783  // **TODO** handle compession
784  if (elf_mem) {
785  strtab_names = (char *) (elf_mem + sec[strtab].sh_offset);
786  } else {
787  if (!(strtab_names = (char *) malloc(sec[strtab].sh_size))) {
788  dprintf("Not enough memory.\n");
789  free_and_return(-1);
790  }
791  lseek(elf_handle, sec[strtab].sh_offset, SEEK_SET);
792  read(elf_handle, strtab_names, sec[strtab].sh_size);
793  }
794 
795 
796  // Loading symtab.
797  // **TODO** handle compession
798  if (elf_mem) {
799  sym = (struct elf_symbol_t *) (elf_mem + sec[symtab].sh_offset);
800  } else {
801  if (!(sym = (struct elf_symbol_t *) malloc(sec[symtab].sh_size))) {
802  dprintf("Not enough memory.\n");
803  free_and_return(-1);
804  }
805  lseek(elf_handle, sec[symtab].sh_offset, SEEK_SET);
806  read(elf_handle, sym, sec[symtab].sh_size);
807  }
808 
809  // Parsing sections to find relocation sections.
810  for (i = 0; i < head.e_shnum; i++) {
811  if (sec[i].sh_type != REL)
812  continue;
813  dprintf("Section %i (%s) contains relocations for section %i (%s):\n",
814  i, names + sec[i].sh_name, sec[i].sh_info, names + sec[sec[i].sh_info].sh_name);
815 
816  if (sec[i].sh_entsize != sizeof(struct elf_reloc_t)) {
817  dprintf("Warning: inconsistancy in relocation table.\n");
818  free_and_return(-1);
819  }
820 
821  // Loading relocation section.
822  // **TODO** handle compession
823  if (elf_mem) {
824  reloc_section = (char *)(elf_mem + sec[i].sh_offset);
825  } else {
826  lseek(elf_handle, sec[i].sh_offset, SEEK_SET);
827  if (!(reloc_section = (char *) malloc(sec[i].sh_size))) {
828  dprintf("Not enough memory.\n");
829  free_and_return(-1);
830  }
831  lseek(elf_handle, sec[i].sh_offset, SEEK_SET);
832  read(elf_handle, reloc_section, sec[i].sh_size);
833  }
834 
835  // We found one relocation section, let's parse it to relocate.
836  dprintf(" Num: Offset Type Symbol\n");
837  for (j = 0; j < (sec[i].sh_size / sec[i].sh_entsize); j++) {
838  int sym_n;
839 
840  reloc = *((struct elf_reloc_t *) (reloc_section + j * sec[i].sh_entsize));
841 
842  sym_n = reloc.r_info >> 8;
843  dprintf("%6i: %08X %-14s %3i: ", j, reloc.r_offset, reloc_types[reloc.r_info & 255], sym_n);
844 
845  switch(sym[sym_n].st_info & 15) {
846  case NOTYPE:
847  rprintf("external symbol reloc to symbol %s\n", strtab_names + sym[sym_n].st_name);
848  if (!(s = erl_find_symbol(strtab_names + sym[sym_n].st_name))) {
849  printf("%s: Symbol not found, adding as loosy relocation.\n", strtab_names + sym[sym_n].st_name);
850  add_loosy(erl_record, erl_record->bytes + sec[sec[i].sh_info].sh_addr + reloc.r_offset, reloc.r_info & 255, strtab_names + sym[sym_n].st_name);
851  } else {
852  dprintf("Found symbol at %08X, relocating.\n", s->address);
853  if (apply_reloc(erl_record->bytes + sec[sec[i].sh_info].sh_addr + reloc.r_offset, reloc.r_info & 255, s->address) < 0) {
854  dprintf("Something went wrong in relocation.");
855  free_and_return(-1);
856  }
857  add_dependancy(erl_record, s->provider);
858  }
859  break;
860  case SECTION:
861  rprintf("internal section reloc to section %i (%s)\n", sym[sym_n].st_shndx, names + sec[sym[sym_n].st_shndx].sh_name);
862  dprintf("Relocating at %08X.\n", erl_record->bytes + sec[sym[sym_n].st_shndx].sh_addr);
863  if (apply_reloc(erl_record->bytes + sec[sec[i].sh_info].sh_addr + reloc.r_offset, reloc.r_info & 255, (u32) (erl_record->bytes + sec[sym[sym_n].st_shndx].sh_addr)) < 0) {
864  dprintf("Something went wrong in relocation.");
865  free_and_return(-1);
866  }
867  break;
868  case OBJECT:
869  case FUNC:
870  rprintf("internal relocation to symbol %s\n", strtab_names + sym[sym_n].st_name);
871  if ((s = erl_find_symbol(strtab_names + sym[sym_n].st_name))) {
872  dprintf("Symbol already exists at %08X. Let's use it instead.\n", s->address);
873  if (apply_reloc(erl_record->bytes + sec[sec[i].sh_info].sh_addr + reloc.r_offset, reloc.r_info & 255, s->address) < 0) {
874  dprintf("Something went wrong in relocation.");
875  free_and_return(-1);
876  }
877  add_dependancy(erl_record, s->provider);
878  } else {
879  dprintf("Relocating at %08X.\n", erl_record->bytes + sec[sym[sym_n].st_shndx].sh_addr + sym[sym_n].st_value);
880  if (apply_reloc(erl_record->bytes + sec[sec[i].sh_info].sh_addr + reloc.r_offset, reloc.r_info & 255, (u32) (erl_record->bytes + sec[sym[sym_n].st_shndx].sh_addr + sym[sym_n].st_value)) < 0) {
881  dprintf("Something went wrong in relocation.");
882  free_and_return(-1);
883  }
884  }
885  break;
886  default:
887  rprintf("Unknown relocation. Bug inside.\n");
888  free_and_return(-1);
889  }
890  }
891  if (!elf_mem)
892  free(reloc_section);
893  }
894 
895  dprintf(" Num: Value Size Type Bind Ndx Name\n");
896  for (i = 0; i < sec[symtab].sh_size / sec[symtab].sh_entsize; i++) {
897  if (((sym[i].st_info >> 4) == GLOBAL) || ((sym[i].st_info >> 4) == WEAK)) {
898  if ((sym[i].st_info & 15) != NOTYPE) {
899  dprintf("Export symbol:\n");
900  if (add_symbol(erl_record, strtab_names + sym[i].st_name, ((u32)erl_record->bytes) + sec[sym[i].st_shndx].sh_addr + sym[i].st_value) < 0) {
901  dprintf("Symbol probably already exists, let's ignore that.\n");
902 // free_and_return(-1);
903  }
904  }
905  }
906 
907  dprintf("%6i: %08X %08X %-7s %-6s %6i %-10s : %s\n", i,
908  sym[i].st_value, sym[i].st_size, symbol_types[sym[i].st_info & 15],
909  binding_types[sym[i].st_info >> 4], sym[i].st_shndx,
910  sym[i].st_name ? strtab_names + sym[i].st_name : "(null)",
911  sym[i].st_shndx ? names + sec[sym[i].st_shndx].sh_name : "(null)");
912  }
913 
914 #ifdef _EE
915  FlushCache(2);
916  FlushCache(0);
917 #endif
918 
919  *p_erl_record = erl_record;
920 
921  free_and_return(0);
922 }
#define NOTYPE
Definition: erl.c:193
static struct erl_record_t * allocate_erl_record()
Definition: erl.c:349
#define OBJECT
Definition: erl.c:194
#define REL_TYPE
Definition: erl.c:187
#define GLOBAL
Definition: erl.c:191
#define rprintf(a...)
Definition: erl.c:34
#define FUNC
Definition: erl.c:195
#define free_and_return(code)
static void add_loosy(struct erl_record_t *erl, u8 *reloc, int type, const char *symbol)
Definition: erl.c:499
#define NOBITS
Definition: erl.c:189
#define PROGBITS
Definition: erl.c:188
#define SECTION
Definition: erl.c:196
#define WEAK
Definition: erl.c:192
#define REL
Definition: erl.c:190
u32 sh_addr
Definition: erl.c:245
u32 sh_offset
Definition: erl.c:245
u32 sh_entsize
Definition: erl.c:246
u32 sh_link
Definition: erl.c:246
u32 sh_addralign
Definition: erl.c:246
u32 sh_info
Definition: erl.c:246
u32 sh_name
Definition: erl.c:245
u32 sh_size
Definition: erl.c:245
u32 sh_flags
Definition: erl.c:245
u32 sh_type
Definition: erl.c:245
unsigned char u8
Definition: tamtypes.h:23

References add_dependancy(), add_loosy(), add_symbol(), align(), allocate_erl_record(), apply_reloc(), erl_loader_t::bytes, elf_header_t::cook, dprintf, elf_header_t::e_ehsize, elf_header_t::e_entry, elf_header_t::e_flags, elf_header_t::e_ident, elf_header_t::e_machine, elf_header_t::e_phentsize, elf_header_t::e_phnum, elf_header_t::e_phoff, elf_header_t::e_shentsize, elf_header_t::e_shnum, elf_header_t::e_shoff, elf_header_t::e_shstrndx, elf_header_t::e_type, elf_header_t::e_version, ERL_DYN_ADDR, erl_find_symbol(), ERL_FLAG_STATIC, erl_loader_t::flags, FlushCache(), free_and_return, erl_loader_t::fullsize, FUNC, GLOBAL, NOBITS, NOTYPE, OBJECT, PROGBITS, elf_reloc_t::r_info, elf_reloc_t::r_offset, REL, REL_TYPE, rprintf, s, SECTION, elf_section_t::sh_addr, elf_section_t::sh_addralign, elf_section_t::sh_entsize, elf_section_t::sh_flags, elf_section_t::sh_info, elf_section_t::sh_link, elf_section_t::sh_name, elf_section_t::sh_offset, elf_section_t::sh_size, elf_section_t::sh_type, elf_symbol_t::st_name, elf_symbol_t::st_shndx, elf_symbol_t::st_value, and WEAK.

Referenced by load_erl().

◆ unload_erl()

int unload_erl ( struct erl_record_t erl)

Definition at line 1084 of file erl.c.

1084  {
1085  struct symbol_t * s;
1086  struct dependancy_t * p;
1087 
1088  dprintf("Unloading module %s.\n", erl->name ? erl->name : "(noname)");
1089 
1090  if ((erl->flags) & ERL_FLAG_STICKY) {
1091  dprintf("Module is sticky, won't unload.\n");
1092  return 0;
1093  }
1094 
1095  for (p = dependancy_root; p; p = p->next) {
1096  if (p->provider == erl) {
1097  dprintf("Other modules depend on it, won't unload.\n");
1098  return 0;
1099  }
1100  }
1101 
1102  if ((s = erl_find_local_symbol("_fini", erl))) {
1103  dprintf("_fini = %08X\n", s->address);
1104 #ifdef _EE
1105  ((func_t)s->address)();
1106 #endif
1107  }
1108 
1109  if (erl->dependancies)
1111 
1112  erl_flush_symbols(erl);
1113 
1114  destroy_dependancy_r(erl);
1115 
1116  destroy_erl_record(erl);
1117 
1118  return 1;
1119 }
static void destroy_dependancy_r(struct erl_record_t *erl)
Definition: erl.c:495
#define ERL_FLAG_STICKY
Definition: erl.h:24

References erl_loader_t::dependancies, dependancy_root, destroy_dependancy_r(), destroy_erl_record(), dprintf, erl_find_local_symbol(), ERL_FLAG_STICKY, erl_flush_symbols(), erl_loader_t::flags, erl_loader_t::name, dependancy_t::next, dependancy_t::provider, r_unload_dependancies(), and s.

Referenced by load_erl(), and r_unload_dependancies().

Variable Documentation

◆ _init_erl_prefix

char _init_erl_prefix[256] = ""

◆ _init_load_erl

erl_loader_t _init_load_erl = _init_load_erl_wrapper_from_file

Definition at line 938 of file erl.c.

Referenced by load_erl().

◆ dependancy_root

struct dependancy_t* dependancy_root = 0
static

Definition at line 283 of file erl.c.

Referenced by add_dependancy(), destroy_dependancy(), destroy_dependancy_r(), and unload_erl().

◆ erl_record_root

struct erl_record_t* erl_record_root = 0
static

◆ global_symbols

htab* global_symbols = 0
static

Definition at line 278 of file erl.c.

Referenced by add_symbol(), and erl_find_symbol().

◆ local_names

const char* local_names[]
static
Initial value:
= {
"_init",
"_fini",
"erl_id",
"erl_dependancies",
"erl_copyright",
"erl_version",
"_start",
0
}

Definition at line 205 of file erl.c.

Referenced by is_local().

◆ loosy_relocs

htab* loosy_relocs = 0
static

Definition at line 279 of file erl.c.

Referenced by add_loosy(), and fix_loosy().

◆ symbol_recycle

reroot* symbol_recycle = 0
static

Definition at line 329 of file erl.c.

Referenced by create_symbol(), and destroy_symbol().