1 /*---------------------------------------------------------------------------* 2 Project: OS Dynamic Load APIs 3 File: OSDynLoad.h 4 5 Copyright (C) Nintendo. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 *---------------------------------------------------------------------------*/ 14 15 #ifndef __OSDYNLOAD_H 16 #define __OSDYNLOAD_H 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 /* ---------------------------------------------------------------- */ 23 /* opaque module handle type */ 24 /* ---------------------------------------------------------------- */ 25 typedef void * OSDynLoad_ModuleHandle; 26 27 /* ---------------------------------------------------------------- */ 28 /* the core has a special handle value */ 29 /* ---------------------------------------------------------------- */ 30 #define MAINPROGRAM_MODULE_HANDLE ((OSDynLoad_ModuleHandle)(-1)) 31 32 /* ---------------------------------------------------------------- */ 33 /* entrypoint function type and default prototype */ 34 /* ---------------------------------------------------------------- */ 35 #define OSDYNLOAD_ENTRY_REASON_LOAD 1 36 #define OSDYNLOAD_ENTRY_REASON_UNLOAD 2 37 #define OSDYNLOAD_ENTRY_REASON_MAX OSDYNLOAD_ENTRY_REASON_UNLOAD 38 typedef int (*pf_rpl_entry)(OSDynLoad_ModuleHandle aHandle, int aReason); 39 int rpl_entry(OSDynLoad_ModuleHandle aHandle, int aReason); 40 void __rpl_call_dtors(void); 41 42 /* ---------------------------------------------------------------- */ 43 /* module load notification callbacks */ 44 /* ---------------------------------------------------------------- */ 45 typedef struct _OSDynLoad_NotifyHdr 46 { 47 char *mpName; /* allocated C string for full path of file */ 48 unsigned int mDebug_TextAddr; /* address where TEXT segment of RPX/RPL is loaded */ 49 unsigned int mDebug_TextOffset; /* offset from linked address for the loaded TEXT segment */ 50 unsigned int mDebug_TextSize; /* size of loaded TEXT segment */ 51 unsigned int mDebug_DataAddr; /* address where DATA and BSS segment of RPX/RPL is loaded */ 52 unsigned int mDebug_DataOffset; /* offset from linked address for the loaded DATA and BSS segment */ 53 unsigned int mDebug_DataSize; /* size of loaded DATA and BSS segment */ 54 unsigned int mDebug_ReadAddr; /* address where RODATA segment of RPX/RPL is loaded */ 55 unsigned int mDebug_ReadOffset; /* offset from linked address for the loaded RODATA segment */ 56 unsigned int mDebug_ReadSize; /* size of loaded RODATA segment */ 57 } OSDynLoad_NotifyHdr; 58 59 /* ---------------------------------------------------------------- */ 60 /* OSDynLoad_AcquireContainingModule restriction flags */ 61 /* for OSDynLoad_AcquireContainingModule */ 62 /* ---------------------------------------------------------------- */ 63 typedef enum _OSDynLoad_SegmentRestrictionFlags 64 { 65 OSDynLoad_SegmentRestriction_None, /* normal case where you do not care or do not know whether the pointer is in the */ 66 /* CODE or DATA segment */ 67 OSDynLoad_SegmentRestriction_Code, /* you want to be sure that the pointer is in the CODE segment; failure if DATA */ 68 OSDynLoad_SegmentRestriction_Data /* you want to be sure that the pointer is in the DATA segment; failure if CODE */ 69 } OSDynLoad_SegmentRestrictionFlags; 70 71 /*---------------------------------------------------------------------------* 72 Name: OSDynLoad_GetNumberOfRPLs 73 74 Description: Return the number of loaded RPLs. 75 76 Concerns: For development only. This function will return 0 in a 77 production build. 78 79 Arguments: None. 80 81 Returns: The number of loaded RPLs. 82 83 *---------------------------------------------------------------------------*/ 84 int OSDynLoad_GetNumberOfRPLs(void); 85 86 /*---------------------------------------------------------------------------* 87 Name: OSDynLoad_GetRPLInfo 88 89 Description: If possible, it will fill infobuffer with a maximum of count 90 elements beginning with the index RPL[index]. If there are 91 fewer RPLs than count, the remaining elements will be cleared. 92 If count is smaller than what OSDynLoad_GetNumberOfRPLs 93 returned, call this function repeatedly with an increasing 94 index. 95 96 Concerns: For development only. This function will return 1 in a 97 production build if count is 0 otherwise it will return 0. 98 99 Note that the RPLs are not necessarily in order of launch. 100 101 Arguments: index - the RPL you want in infobuffer[0]. 102 count - the number of elements in infobuffer 103 infobuffer - an allocated or fixed size array of OSDynLoad_NotifyHdr 104 105 Returns: 0 if called when an RPL has been loaded since OSDynLoad_GetNumberOfRPLs 106 was called; if it returns 0, you must start over with 107 OSDynLoad_GetNumberOfRPLs. 108 109 1 for success. 110 111 *---------------------------------------------------------------------------*/ 112 int OSDynLoad_GetRPLInfo(unsigned int index, unsigned int count, OSDynLoad_NotifyHdr *infobuffer); 113 114 typedef void (*OSDynLoad_pfNotifyFunc)(OSDynLoad_ModuleHandle aModuleHandle, void *apUserArg, int aIsLoad, OSDynLoad_NotifyHdr const *apNotify); 115 116 int OSDynLoad_AddNotifyCallback(OSDynLoad_pfNotifyFunc aFunc, void *pUserArg); 117 void OSDynLoad_DelNotifyCallback(OSDynLoad_pfNotifyFunc aFunc, void *pUserArg); 118 119 /* ---------------------------------------------------------------- */ 120 /* legacy old spelling of OSDynLoad_AddNotifyCallback */ 121 /* ---------------------------------------------------------------- */ 122 int OSDynLoad_AddNofifyCallback(OSDynLoad_pfNotifyFunc aFunc, void *pUserArg); 123 124 /* ---------------------------------------------------------------- */ 125 /* allocator override - default allocator uses default heap */ 126 /* ---------------------------------------------------------------- */ 127 typedef int (*OSDynLoad_pfMemAlloc)(int aMemBytes, int aMemAlign, void **appRetPtr); 128 typedef void (*OSDynLoad_pfMemFree)(void *pAddr); 129 int OSDynLoad_SetAllocator(OSDynLoad_pfMemAlloc aAlloc, OSDynLoad_pfMemFree aFree); 130 int OSDynLoad_GetAllocator(OSDynLoad_pfMemAlloc *apRetAlloc, OSDynLoad_pfMemFree *apRetFree); 131 132 /* ---------------------------------------------------------------- */ 133 /* tls allocator override - default allocator uses default heap */ 134 /* for use by the loader to allocate the tls framework and data images in threads */ 135 /* can only be changed in __preinit_user */ 136 /* ---------------------------------------------------------------- */ 137 int OSDynLoad_SetTLSAllocator(OSDynLoad_pfMemAlloc aAlloc, OSDynLoad_pfMemFree aFree); 138 int OSDynLoad_GetTLSAllocator(OSDynLoad_pfMemAlloc *apRetAlloc, OSDynLoad_pfMemFree *apRetFree); 139 140 /* ---------------------------------------------------------------- */ 141 /* acquire/release module */ 142 /* ---------------------------------------------------------------- */ 143 int OSDynLoad_Acquire(char const *apBaseModuleName, OSDynLoad_ModuleHandle *apRetHandle); 144 void OSDynLoad_Release(OSDynLoad_ModuleHandle aModuleHandle); 145 146 /* ---------------------------------------------------------------- */ 147 /* test if module is loaded */ 148 /* module is loaded if return == 0 and *apRetHandle != 0 */ 149 /* ---------------------------------------------------------------- */ 150 int OSDynLoad_IsModuleLoaded(char const *apFileName, OSDynLoad_ModuleHandle *apRetHandle); 151 152 /* ---------------------------------------------------------------- */ 153 /* retrieve the name of a module (the one used in dynamic linking) */ 154 /* ---------------------------------------------------------------- */ 155 int OSDynLoad_GetModuleName(OSDynLoad_ModuleHandle aModuleHandle, char *apRetBuffer, int *apBufferSize); 156 157 /* ---------------------------------------------------------------- */ 158 /* find an export in a module by name */ 159 /* log2n;n=num exported symbols, string comparison (bin search) */ 160 /* ---------------------------------------------------------------- */ 161 int OSDynLoad_FindExport(OSDynLoad_ModuleHandle aModuleHandle, int aTypeIsData, char const *apExportName, void **appRetAddr); 162 163 /* ---------------------------------------------------------------- */ 164 /* find a loader tag that was embedded in an RPL at makerpl stage*/ 165 /* ---------------------------------------------------------------- */ 166 int OSDynLoad_FindTag(OSDynLoad_ModuleHandle aModuleHandle, char const *apTag, char *apRetBuffer, int *apBufferSize); 167 168 /* ---------------------------------------------------------------- */ 169 /* free TLS memory allocated in a thread */ 170 /* ---------------------------------------------------------------- */ 171 void __OSDynLoad_TLSExitThread(OSThread *apThread); 172 173 /*---------------------------------------------------------------------------* 174 Name: OSDynLoad_AcquireContainingModule 175 176 Description: Load an RPL module that contains an object, returning its handle. 177 178 Arguments: apObject global or static object in some RPL module 179 aRestrict a flag where you say that apObject must be in CODE or 180 DATA or that there is no restriction 181 apRetHandle pointer to memory to receive handle of loaded module 182 that contains apObject. Since apObject has an 183 address, it must already be loaded so this function 184 actually just increases the ref count of the 185 RPL module. apObject cannot be a stack based or 186 allocated (for example, malloc or new) object. 187 188 Caveat: Zero size objects will not be found if they are the last object in 189 a code or data segment. 190 191 Returns: 0 for success. OSDYNLOAD_ERR_xxx on failure 192 OSDYNLOAD_ERR_BAD_HANDLE_RETURN_POINTER if apRetHandle parameter is NULL 193 OSDYNLOAD_ERR_NULL_OBJECT if apObject parameter is NULL 194 OSDYNLOAD_ERR_CONTAINING_MODULE_NOT_FOUND if module not found 195 *---------------------------------------------------------------------------*/ 196 int OSDynLoad_AcquireContainingModule(void *apObject, OSDynLoad_SegmentRestrictionFlags aRestrict, OSDynLoad_ModuleHandle *apRetHandle); 197 198 /* ---------------------------------------------------------------- */ 199 /* Loader Heap Statistics */ 200 /* ---------------------------------------------------------------- */ 201 typedef struct _OSDynLoad_LoaderHeapStatistics 202 { 203 unsigned int mCodeHeap_MemBytesUsed; /* current total amount in bytes of allocations in code heap */ 204 unsigned int mCodeHeap_UsedNumAllocations; /* current number of allocations in code heap */ 205 unsigned int mCodeHeap_MemBytesFree; /* current total amount of free memory in code heap */ 206 unsigned int mCodeHeap_MemLargestFreeBlock; /* largest allocation available in code heap */ 207 unsigned int mDataHeap_MemBytesUsed; /* current total amount in bytes of allocations in data heap */ 208 unsigned int mDataHeap_UsedNumAllocations; /* current number of allocations in data heap */ 209 } OSDynLoad_LoaderHeapStatistics; 210 211 /*---------------------------------------------------------------------------* 212 Name: OSDynLoad_GetLoaderHeapStatistics 213 214 Description: Return heap information from the loader. 215 216 Arguments: apRetLoaderHeapStatistics pointer to memory to receive OSDynLoad_LoaderHeapStatistics. 217 apRetLoaderHeapStatistics can be global, stack based or 218 allocated (for example, malloc or new). 219 220 Returns: 0 for success. OSDYNLOAD_ERR_xxx on failure 221 OSDYNLOAD_ERR_LOADER_MEM_INFO_BAD_PTR if apRetLoaderHeapStatistics is not valid memory 222 OSDYNLOAD_ERR_NULL_LOADER_MEM_INFO if apRetLoaderHeapStatistics parameter is NULL 223 224 *---------------------------------------------------------------------------*/ 225 int OSDynLoad_GetLoaderHeapStatistics(OSDynLoad_LoaderHeapStatistics *apRetLoaderHeapStatistics); 226 227 #ifdef __cplusplus 228 } // extern "C" 229 #endif 230 231 #define OSDYNLOAD_ERRCODE(x) ((int)(0xBAD10000 | (x))) 232 233 #define OSDYNLOAD_ERR_NONE 0 234 #define OSDYNLOAD_ERR_UNKNOWN OSDYNLOAD_ERRCODE(0x001) 235 #define OSDYNLOAD_ERR_MEMORY_ALLOCATION_FAILURE OSDYNLOAD_ERRCODE(0x002) 236 #define OSDYNLOAD_ERR_BAD_MODULE_HANDLE OSDYNLOAD_ERRCODE(0x003) 237 #define OSDYNLOAD_ERR_FILE_TOO_SMALL OSDYNLOAD_ERRCODE(0x004) 238 #define OSDYNLOAD_ERR_BAD_ELF_HEADER OSDYNLOAD_ERRCODE(0x005) 239 #define OSDYNLOAD_ERR_NOT_32BIT_ELF OSDYNLOAD_ERRCODE(0x006) 240 #define OSDYNLOAD_ERR_WRONG_ENDIANNESS OSDYNLOAD_ERRCODE(0x007) 241 #define OSDYNLOAD_ERR_UNSUPPORTED_HEADER_VERSION OSDYNLOAD_ERRCODE(0x008) 242 #define OSDYNLOAD_ERR_WRONG_TARGET_MACHINE OSDYNLOAD_ERRCODE(0x009) 243 #define OSDYNLOAD_ERR_UNSUPPORTED_FILE_VERSION OSDYNLOAD_ERRCODE(0x00A) 244 #define OSDYNLOAD_ERR_NO_SECTION_HEADERS OSDYNLOAD_ERRCODE(0x00B) 245 #define OSDYNLOAD_ERR_MALFORMED_RPL OSDYNLOAD_ERRCODE(0x00C) 246 #define OSDYNLOAD_ERR_NOT_CAFE_RPL OSDYNLOAD_ERRCODE(0x00D) 247 #define OSDYNLOAD_ERR_NOTIFY_FUNCPTR_IS_NULL OSDYNLOAD_ERRCODE(0x00E) 248 #define OSDYNLOAD_ERR_NULL_FILENAME OSDYNLOAD_ERRCODE(0x00F) 249 #define OSDYNLOAD_ERR_EMPTY_FILENAME OSDYNLOAD_ERRCODE(0x010) 250 #define OSDYNLOAD_ERR_BAD_HANDLE_RETURN_POINTER OSDYNLOAD_ERRCODE(0x011) 251 #define OSDYNLOAD_ERR_NO_FILENAME OSDYNLOAD_ERRCODE(0x012) 252 #define OSDYNLOAD_ERR_LOADER_RETURNED_NO_DATA OSDYNLOAD_ERRCODE(0x013) 253 #define OSDYNLOAD_ERR_LOADER_PTR_BAD OSDYNLOAD_ERRCODE(0x014) 254 #define OSDYNLOAD_ERR_NULL_LOADER OSDYNLOAD_ERRCODE(0x015) 255 #define OSDYNLOAD_ERR_CANT_LOAD_INSIDE_MODULE_ENTRYPOINT OSDYNLOAD_ERRCODE(0x016) 256 #define OSDYNLOAD_ERR_ALLOCATOR_PTR_BAD OSDYNLOAD_ERRCODE(0x017) 257 #define OSDYNLOAD_ERR_MODULE_HAS_NONRELOCATABLE_CODE OSDYNLOAD_ERRCODE(0x018) 258 #define OSDYNLOAD_ERR_CANT_LINK_BLIND_SYMBOL OSDYNLOAD_ERRCODE(0x019) 259 #define OSDYNLOAD_ERR_IMPORT_NOT_FOUND_IN_EXPORTING_MODULE OSDYNLOAD_ERRCODE(0x01A) 260 #define OSDYNLOAD_ERR_MODULE_HAS_NO_DATA_EXPORTS OSDYNLOAD_ERRCODE(0x01B) 261 #define OSDYNLOAD_ERR_MODULE_HAS_NO_CODE_EXPORTS OSDYNLOAD_ERRCODE(0x01C) 262 #define OSDYNLOAD_ERR_EXPORT_NOT_FOUND OSDYNLOAD_ERRCODE(0x01D) 263 #define OSDYNLOAD_ERR_BAD_ARGUMENT OSDYNLOAD_ERRCODE(0x01E) 264 #define OSDYNLOAD_ERR_BUFFER_TOO_SMALL OSDYNLOAD_ERRCODE(0x01F) 265 #define OSDYNLOAD_ERR_LOADER_FAILURE OSDYNLOAD_ERRCODE(0x021) 266 #define OSDYNLOAD_ERR_TAG_NOT_FOUND OSDYNLOAD_ERRCODE(0x022) 267 #define OSDYNLOAD_ERR_MODULE_NOT_FOUND OSDYNLOAD_ERRCODE(0x023) 268 #define OSDYNLOAD_ERR_ALLOC_FAILED_LD_SECT_INFO OSDYNLOAD_ERRCODE(0x024) 269 #define OSDYNLOAD_ERR_ALLOC_FAILED_MAIN_NOTIF_ENTRY OSDYNLOAD_ERRCODE(0x025) 270 #define OSDYNLOAD_ERR_FAILED_DEBUG_SET_CALLBACK OSDYNLOAD_ERRCODE(0x026) 271 #define OSDYNLOAD_ERR_NULL_OBJECT OSDYNLOAD_ERRCODE(0x027) 272 #define OSDYNLOAD_ERR_CONTAINING_MODULE_NOT_FOUND OSDYNLOAD_ERRCODE(0x028) 273 #define OSDYNLOAD_ERR_LOAD_ENTRYPOINT_FAILED OSDYNLOAD_ERRCODE(0x029) 274 #define OSDYNLOAD_ERR_UNKNOWN_MOD_FOR_HANDLE OSDYNLOAD_ERRCODE(0x02A) 275 #define OSDYNLOAD_ERR_LOADER_BUSY OSDYNLOAD_ERRCODE(0x02B) 276 #define OSDYNLOAD_ERR_LOADER_MEM_INFO_BAD_PTR OSDYNLOAD_ERRCODE(0x02C) // apRetLoaderHeapStatistics is invalid memory 277 #define OSDYNLOAD_ERR_NULL_LOADER_MEM_INFO OSDYNLOAD_ERRCODE(0x02D) // apRetLoaderHeapStatistics is null 278 #define OSDYNLOAD_ERR_PREVIOUS_LOADER_FAILURE OSDYNLOAD_ERRCODE(0x02E) 279 #define OSDYNLOAD_ERR_SYS_HEAP_MEMORY_ALLOCATION_FAILURE OSDYNLOAD_ERRCODE(0x02F) 280 #define OSDYNLOAD_ERR_TLS_INCONSISTENCY OSDYNLOAD_ERRCODE(0x030) 281 #define OSDYNLOAD_ERR_TLS_ALLOCATOR_UNCHANGEABLE OSDYNLOAD_ERRCODE(0x031) 282 #define OSDYNLOAD_ERR_TLS_TOO_MANY_MODULES OSDYNLOAD_ERRCODE(0x032) 283 #define OSDYNLOAD_ERR_TLS_FINDEXPORT_UNSUPPORTED OSDYNLOAD_ERRCODE(0x033) 284 #define OSDYNLOAD_ERR_TAG_ADDRSPACE_WRONG OSDYNLOAD_ERRCODE(0x034) 285 #define OSDYNLOAD_ERR_INVAL_TAG_VALUE_RET_BUF OSDYNLOAD_ERRCODE(0x035) 286 #define OSDYNLOAD_ERR_INVAL_TAG_VALUE_SIZE_RET_BUF OSDYNLOAD_ERRCODE(0x036) 287 #define OSDYNLOAD_ERR_INVAL_TAG_INPUT_BUF OSDYNLOAD_ERRCODE(0x037) 288 #define OSDYNLOAD_ERR_TAG_SNPRINTF_INTERNAL OSDYNLOAD_ERRCODE(0x038) 289 #define OSDYNLOAD_ERR_TAG_VALUE_SIZE_IS_ZERO OSDYNLOAD_ERRCODE(0x039) 290 #define OSDYNLOAD_ERR_MISSING_SHSTRTAB_INDEX OSDYNLOAD_ERRCODE(0x03A) 291 #define OSDYNLOAD_ERR_MISSING_SHSTRTAB OSDYNLOAD_ERRCODE(0x03B) 292 #define OSDYNLOAD_ERR_MISSING_IMPORT_NAME OSDYNLOAD_ERRCODE(0x03C) 293 #define OSDYNLOAD_ERR_MISSING_TLS_DATA OSDYNLOAD_ERRCODE(0x03D) 294 #define OSDYNLOAD_ERR_MISSING_RPX_ENTRYPOINT OSDYNLOAD_ERRCODE(0x03E) 295 #define OSDYNLOAD_ERR_DISPLACEMENT_TOO_FAR OSDYNLOAD_ERRCODE(0x03F) 296 297 /* ---------------------------------------------------------------- */ 298 /* for exporting via in-code (not in header) definition decoration */ 299 /* ---------------------------------------------------------------- */ 300 301 #define RPL_EXPORT_FUNC(r, f, a) \ 302 r f a; \ 303 void * const __attribute__((section(".export"))) fexport_ ## f = (void *)f; \ 304 r f a 305 306 #define RPL_EXPORT_DATA(t, d) \ 307 extern t d; \ 308 void * const __attribute__((section(".export"))) dexport_ ## d = (void *)&d; \ 309 t d 310 311 #define RPL_EXPORT_DATA_ARRAY(t, d, num) \ 312 extern t d[num]; \ 313 void * const __attribute__((section(".export"))) dexport_ ## d = (void *)&d; \ 314 t d[num] 315 316 #define RPL_EXPORT_CLASS_FUNC(r, c, f, a) \ 317 void * const __attribute__((section(".export"))) fexport_ ## c ## f = (void *)c::f; \ 318 r c::f a 319 320 #define RPL_EXPORT_CLASS_STATIC_DATA(t, c, d) \ 321 void * const __attribute__((section(".export"))) dexport_ ## c ## d = (void *)&c::d; \ 322 t c::d 323 324 #define RPL_EXPORT_CLASS_STATIC_DATA_ARRAY(t, c, d, num) \ 325 void * const __attribute__((section(".export"))) dexport_ ## c ## d = (void *)&c::d; \ 326 t c::d[num] 327 328 #endif // __OSDYNLOAD_H 329