summaryrefslogtreecommitdiff
path: root/include/rvl/OS/OSLink.h
blob: ddb043507b5f94923478b691896e84d2d90ee165 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#ifndef OSLINK_H
#define OSLINK_H

#include "common.h"

#ifdef __cplusplus
extern "C" {
#endif

#define OS_MODULE_VERSION 3

typedef struct OSModuleHeader OSModuleHeader;

typedef u32 OSModuleID;
typedef struct OSModuleQueue OSModuleQueue;
typedef struct OSModuleLink OSModuleLink;
typedef struct OSModuleInfo OSModuleInfo;
typedef struct OSSectionInfo OSSectionInfo;
typedef struct OSImportInfo OSImportInfo;
typedef struct OSRel OSRel;

// OSModuleQueue __OSModuleList : 0x800030C8;
// void* __OSStringTable : 0x800030D0;
extern OSModuleQueue __OSModuleList;
extern void *__OSStringTable;

struct OSModuleQueue {
    OSModuleInfo *head;
    OSModuleInfo *tail;
};

struct OSModuleLink {
    OSModuleInfo *next;
    OSModuleInfo *prev;
};

struct OSSectionInfo {
    u32 offset;
    u32 size;
};

struct OSModuleInfo {
    OSModuleID id;         // unique identifier for the module
    OSModuleLink link;     // doubly linked list of modules
    u32 numSections;       // # of sections
    u32 sectionInfoOffset; // offset to section info table
    u32 nameOffset;        // offset to module name
    u32 nameSize;          // size of module name
    u32 version;           // version number
};

struct OSModuleHeader {
    // CAUTION: info must be the 1st member
    OSModuleInfo info;

    // OS_MODULE_VERSION == 1
    u32 bssSize; // total size of bss sections in bytes
    u32 relOffset;
    u32 impOffset;
    u32 impSize;          // size in bytes
    u8 prologSection;     // section # for prolog function
    u8 epilogSection;     // section # for epilog function
    u8 unresolvedSection; // section # for unresolved function
    u8 bssSection;        // section # for bss section (set at run-time)
    u32 prolog;           // prolog function offset
    u32 epilog;           // epilog function offset
    u32 unresolved;       // unresolved function offset

    // OS_MODULE_VERSION == 2
#if (2 <= OS_MODULE_VERSION)
    u32 align;    // module alignment constraint
    u32 bssAlign; // bss alignment constraint
#endif

    // OS_MODULE_VERSION == 3
#if (3 <= OS_MODULE_VERSION)
    u32 fixSize;
#endif
};

#define OSGetSectionInfo(module) ((OSSectionInfo *)(((OSModuleInfo *)(module))->sectionInfoOffset))

#define OS_SECTIONINFO_EXEC 0x1
#define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1)

struct OSImportInfo {
    OSModuleID id; // external module id
    u32 offset;    // offset to OSRel instructions
};

struct OSRel {
    u16 offset; // byte offset from the previous entry
    u8 type;
    u8 section;
    u32 addend;
};

#define R_DOLPHIN_NOP 201     // C9h current offset += OSRel.offset
#define R_DOLPHIN_SECTION 202 // CAh current section = OSRel.section
#define R_DOLPHIN_END 203     // CBh
#define R_DOLPHIN_MRKREF 204  // CCh

BOOL OSLink(OSModuleInfo *newModule, void *bss);
BOOL OSLinkFixed(OSModuleInfo *newModule, void *bss);
BOOL OSUnlink(OSModuleInfo *module);
void OSSetStringTable(void *string_table);
void __OSModuleInit(void);
OSModuleInfo *OSSearchModule(void *ptr, u32 *section, u32 *offset);

#ifdef __cplusplus
};
#endif

#endif /* OSLINK_H */