v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
elf.h
1 /* -*- mode: C; c-basic-offset: 4; intent-tabs-mode: nil -*-
2  *
3  * Sifteo SDK
4  *
5  * Copyright <c> 2012 Sifteo, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #ifndef _SIFTEO_ABI_ELF_H
27 #define _SIFTEO_ABI_ELF_H
28 
29 #include <sifteo/abi/types.h>
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 
36 /*
37  * ELF binary format.
38  *
39  * Loadable programs in this system are standard ELF binaries, however their
40  * instruction set is a special restricted subset of Thumb-2 as defined by the
41  * Sifteo Virtual Machine.
42  *
43  * In addition to standard read-only data, read-write data, and BSS segments,
44  * we support a special metadata segment. This contains a key-value dictionary
45  * of metadata records.
46  *
47  * The contents of the metadata segment is structured as first an array of
48  * key/size words, then a stream of variable-size values. The values must be
49  * aligned according to their natural ABI alignment, and they must not cross
50  * a memory page boundary. Each key occurs at most once in this table; multiple
51  * values with the same key are concatenated by the linker.
52  *
53  * The last _SYSMetadataKey has the MSB set in its 'stride' value.
54  *
55  * Strings are zero-terminated. Additional padding bytes may appear after
56  * any value.
57  */
58 
59 // SVM-specific program header types
60 #define _SYS_ELF_PT_METADATA 0x7000f001 // Metadata key/value dictionary
61 #define _SYS_ELF_PT_LOAD_FASTLZ 0x7000f002 // PT_LOAD, with FastLZ (Level 1) compression
62 
63 struct _SYSMetadataKey {
64  uint16_t stride; // Byte offset from this value to the next
65  uint16_t key; // _SYS_METADATA_*
66 };
67 
68 // Maximum size for a single metadata value
69 #define _SYS_MAX_METADATA_ITEM_BYTES 0x100
70 
71 // System Metadata keys
72 #define _SYS_METADATA_NONE 0x0000 // Ignored. (padding)
73 #define _SYS_METADATA_UUID 0x0001 // Binary UUID for this specific build
74 #define _SYS_METADATA_BOOT_ASSET 0x0002 // Array of _SYSMetadataBootAsset
75 #define _SYS_METADATA_TITLE_STR 0x0003 // Human readable game title string
76 #define _SYS_METADATA_PACKAGE_STR 0x0004 // DNS-style package string
77 #define _SYS_METADATA_VERSION_STR 0x0005 // Version string
78 #define _SYS_METADATA_ICON_96x96 0x0006 // _SYSMetadataImage
79 #define _SYS_METADATA_NUM_ASLOTS 0x0007 // uint8_t, count of required AssetSlots
80 #define _SYS_METADATA_CUBE_RANGE 0x0008 // _SYSMetadataCubeRange
81 #define _SYS_METADATA_MIN_OS_VERSION 0x0009 // uint32_t minimum OS version required
82 #define _SYS_METADATA_IS_DEMO_OF_STR 0x000a // DNS-style string of the full version of this demo app
83 
84 struct _SYSMetadataBootAsset {
85  uint32_t pHdr; // Virtual address for _SYSAssetGroupHeader
86  _SYSAssetSlot slot; // Asset group slot to load this into
87  uint8_t reserved[3]; // Must be zero;
88 };
89 
90 struct _SYSMetadataCubeRange {
91  uint8_t minCubes;
92  uint8_t maxCubes;
93 };
94 
95 struct _SYSMetadataImage {
96  uint8_t width;
97  uint8_t height;
98  uint8_t frames;
99  uint8_t format;
100  uint32_t groupHdr;
101  uint32_t pData;
102 };
103 
104 /*
105  * Entry point. Our standard entry point is main(), with no arguments
106  * or return values, declared using C linkage.
107  */
108 
109 #ifndef NOT_USERSPACE
110 void main(void);
111 #endif
112 
113 /*
114  * Link-time intrinsics.
115  *
116  * These functions are replaced during link-time optimization.
117  *
118  * Logging supports many standard printf() format specifiers,
119  * as documented in sifteo/macros.h
120  *
121  * To work around limitations in C variadic functions, _SYS_lti_metadata()
122  * supports a format string which specifies what data type each argument
123  * should be cast to. Data types here automatically imply ABI-compatible
124  * alignment and padding:
125  *
126  * "b" = int8_t
127  * "B" = uint8_t
128  * "h" = int16_t
129  * "H" = uint16_t
130  * "i" = int32_t
131  * "I" = uint32_t
132  * "s" = String (NUL terminator is *not* automatically added)
133  *
134  * Counters:
135  * This is a mechanism for generating monotonic unique IDs at link-time.
136  * Every _SYS_lti_counter() call with the same 'name' will return a
137  * different value, starting with zero. Values are assigned in order of
138  * decreasing priority.
139  *
140  * UUIDs:
141  * We support link-time generation of standard UUIDs. For every unique
142  * 'key', the linker will generate a different UUID. Since a full UUID
143  * is too large to return directly, it is accessed as a group of four
144  * little-endian 32-bit words, using values of 'index' from 0 to 3.
145  *
146  * Static initializers:
147  * In global varaibles which aren't themselves constant but which were
148  * initialized to a constant, _SYS_lti_initializer() can be used to retrieve
149  * that initializer value at link-time. If 'require' is 'true', the value
150  * must be resolveable to a constant static initializer of a link error
151  * will result. If 'require' is false, we return the static initializer if
152  * possible, or pass through 'value' without modification if not.
153  */
154 
155 unsigned _SYS_lti_isDebug();
156 void _SYS_lti_abort(bool enable, const char *message);
157 void _SYS_lti_log(const char *fmt, ...);
158 void _SYS_lti_metadata(uint16_t key, const char *fmt, ...);
159 unsigned _SYS_lti_counter(const char *name, int priority);
160 uint32_t _SYS_lti_uuid(unsigned key, unsigned index);
161 const void *_SYS_lti_initializer(const void *value, bool require);
162 bool _SYS_lti_isConstant(unsigned value);
163 
164 
165 #ifdef __cplusplus
166 } // extern "C"
167 #endif
168 
169 #endif