Statistics
| Branch: | Revision:

root / hw / magic-load.c @ 3475187d

History | View | Annotate | Download (4.5 kB)

1
#include "vl.h"
2
#include "disas.h"
3
#include "exec-all.h"
4

    
5
struct exec
6
{
7
  uint32_t a_info;   /* Use macros N_MAGIC, etc for access */
8
  uint32_t a_text;   /* length of text, in bytes */
9
  uint32_t a_data;   /* length of data, in bytes */
10
  uint32_t a_bss;    /* length of uninitialized data area, in bytes */
11
  uint32_t a_syms;   /* length of symbol table data in file, in bytes */
12
  uint32_t a_entry;  /* start address */
13
  uint32_t a_trsize; /* length of relocation info for text, in bytes */
14
  uint32_t a_drsize; /* length of relocation info for data, in bytes */
15
};
16

    
17
#ifdef BSWAP_NEEDED
18
static void bswap_ahdr(struct exec *e)
19
{
20
    bswap32s(&e->a_info);
21
    bswap32s(&e->a_text);
22
    bswap32s(&e->a_data);
23
    bswap32s(&e->a_bss);
24
    bswap32s(&e->a_syms);
25
    bswap32s(&e->a_entry);
26
    bswap32s(&e->a_trsize);
27
    bswap32s(&e->a_drsize);
28
}
29
#else
30
#define bswap_ahdr(x) do { } while (0)
31
#endif
32

    
33
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
34
#define OMAGIC 0407
35
#define NMAGIC 0410
36
#define ZMAGIC 0413
37
#define QMAGIC 0314
38
#define _N_HDROFF(x) (1024 - sizeof (struct exec))
39
#define N_TXTOFF(x)                                                        \
40
    (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :        \
41
     (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
42
#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
43
#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
44
#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
45

    
46
#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
47

    
48
#define N_DATADDR(x) \
49
    (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
50
     : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
51

    
52

    
53
#define ELF_CLASS   ELFCLASS32
54
#define ELF_DATA    ELFDATA2MSB
55
#define ELF_ARCH    EM_SPARC
56

    
57
#include "elf.h"
58

    
59
#ifndef BSWAP_NEEDED
60
#define bswap_ehdr32(e) do { } while (0)
61
#define bswap_phdr32(e) do { } while (0)
62
#define bswap_shdr32(e) do { } while (0)
63
#define bswap_sym32(e) do { } while (0)
64
#ifdef TARGET_SPARC64
65
#define bswap_ehdr64(e) do { } while (0)
66
#define bswap_phdr64(e) do { } while (0)
67
#define bswap_shdr64(e) do { } while (0)
68
#define bswap_sym64(e) do { } while (0)
69
#endif
70
#endif
71

    
72
#define SZ                32
73
#define elf_word        uint32_t
74
#define bswapSZs        bswap32s
75
#include "elf_ops.h"
76

    
77
#ifdef TARGET_SPARC64
78
#undef elfhdr
79
#undef elf_phdr
80
#undef elf_shdr
81
#undef elf_sym
82
#undef elf_note
83
#undef elf_word
84
#undef bswapSZs
85
#undef SZ
86
#define elfhdr                elf64_hdr
87
#define elf_phdr        elf64_phdr
88
#define elf_note        elf64_note
89
#define elf_shdr        elf64_shdr
90
#define elf_sym                elf64_sym
91
#define elf_word        uint64_t
92
#define bswapSZs        bswap64s
93
#define SZ                64
94
#include "elf_ops.h"
95
#endif
96

    
97
int load_elf(const char *filename, uint8_t *addr)
98
{
99
    struct elf32_hdr ehdr;
100
    int retval, fd;
101
    Elf32_Half machine;
102

    
103
    fd = open(filename, O_RDONLY | O_BINARY);
104
    if (fd < 0)
105
        goto error;
106

    
107
    retval = read(fd, &ehdr, sizeof(ehdr));
108
    if (retval < 0)
109
        goto error;
110

    
111
    if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
112
        || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
113
        goto error;
114
    machine = tswap16(ehdr.e_machine);
115
    if (machine == EM_SPARC || machine == EM_SPARC32PLUS) {
116
        struct elf32_phdr phdr;
117

    
118
        bswap_ehdr32(&ehdr);
119

    
120
        if (find_phdr32(&ehdr, fd, &phdr, PT_LOAD))
121
            goto error;
122
        retval = read_program32(fd, &phdr, addr, ehdr.e_entry);
123
        if (retval < 0)
124
            goto error;
125
        load_symbols32(&ehdr, fd);
126
    }
127
#ifdef TARGET_SPARC64
128
    else if (machine == EM_SPARCV9) {
129
        struct elf64_hdr ehdr64;
130
        struct elf64_phdr phdr;
131

    
132
        lseek(fd, 0, SEEK_SET);
133

    
134
        retval = read(fd, &ehdr64, sizeof(ehdr64));
135
        if (retval < 0)
136
            goto error;
137

    
138
        bswap_ehdr64(&ehdr64);
139

    
140
        if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
141
            goto error;
142
        retval = read_program64(fd, &phdr, addr, ehdr64.e_entry);
143
        if (retval < 0)
144
            goto error;
145
        load_symbols64(&ehdr64, fd);
146
    }
147
#endif
148

    
149
    close(fd);
150
    return retval;
151
 error:
152
    close(fd);
153
    return -1;
154
}
155

    
156
int load_aout(const char *filename, uint8_t *addr)
157
{
158
    int fd, size, ret;
159
    struct exec e;
160
    uint32_t magic;
161

    
162
    fd = open(filename, O_RDONLY | O_BINARY);
163
    if (fd < 0)
164
        return -1;
165

    
166
    size = read(fd, &e, sizeof(e));
167
    if (size < 0)
168
        goto fail;
169

    
170
    bswap_ahdr(&e);
171

    
172
    magic = N_MAGIC(e);
173
    switch (magic) {
174
    case ZMAGIC:
175
    case QMAGIC:
176
    case OMAGIC:
177
        lseek(fd, N_TXTOFF(e), SEEK_SET);
178
        size = read(fd, addr, e.a_text + e.a_data);
179
        if (size < 0)
180
            goto fail;
181
        break;
182
    case NMAGIC:
183
        lseek(fd, N_TXTOFF(e), SEEK_SET);
184
        size = read(fd, addr, e.a_text);
185
        if (size < 0)
186
            goto fail;
187
        ret = read(fd, addr + N_DATADDR(e), e.a_data);
188
        if (ret < 0)
189
            goto fail;
190
        size += ret;
191
        break;
192
    default:
193
        goto fail;
194
    }
195
    close(fd);
196
    return size;
197
 fail:
198
    close(fd);
199
    return -1;
200
}
201