mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-12-27 19:06:01 +00:00
Improved ProgramInfo XML generation.
Also added some additional fields. Thanks to 0Liam.
This commit is contained in:
parent
40fc21b5a3
commit
7059bacfce
1 changed files with 309 additions and 76 deletions
|
@ -24,10 +24,18 @@
|
|||
#include "program_info.h"
|
||||
#include "elf_symbol.h"
|
||||
|
||||
/* Global variables. */
|
||||
|
||||
static const char *g_trueString = "True", *g_falseString = "False";
|
||||
static const char *g_nnSdkString = "NintendoSdk_nnSdk";
|
||||
|
||||
/* Function prototypes. */
|
||||
|
||||
static bool programInfoAddNsoMiddlewareListToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const NsoContext *nso_ctx);
|
||||
static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const NsoContext *nso_ctx, bool is_64bit);
|
||||
static bool programInfoGetSdkVersionAndBuildTypeFromSdkNso(ProgramInfoContext *program_info_ctx, char **sdk_version, char **build_type);
|
||||
static bool programInfoAddStringFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, const char *value);
|
||||
static bool programInfoAddNsoApiListToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, ProgramInfoContext *program_info_ctx, const char *api_list_tag, const char *api_entry_prefix, \
|
||||
const char *sdk_prefix);
|
||||
static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, ProgramInfoContext *program_info_ctx);
|
||||
|
||||
bool programInfoInitializeContext(ProgramInfoContext *out, NcaContext *nca_ctx)
|
||||
{
|
||||
|
@ -136,7 +144,7 @@ bool programInfoGenerateAuthoringToolXml(ProgramInfoContext *program_info_ctx)
|
|||
char *xml_buf = NULL;
|
||||
u64 xml_buf_size = 0;
|
||||
|
||||
VersionType2 *sdk_addon_version = &(program_info_ctx->nca_ctx->header.sdk_addon_version);
|
||||
char *sdk_version = NULL, *build_type = NULL;
|
||||
bool is_64bit = (program_info_ctx->npdm_ctx.meta_header->flags.is_64bit_instruction == 1);
|
||||
|
||||
u8 *npdm_acid = (u8*)program_info_ctx->npdm_ctx.acid_header;
|
||||
|
@ -172,53 +180,71 @@ bool programInfoGenerateAuthoringToolXml(ProgramInfoContext *program_info_ctx)
|
|||
goto end;
|
||||
}
|
||||
|
||||
/* Get SDK version and build type strings. */
|
||||
if (!programInfoGetSdkVersionAndBuildTypeFromSdkNso(program_info_ctx, &sdk_version, &build_type)) goto end;
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
|
||||
"<ProgramInfo>\n" \
|
||||
" <SdkVersion>%u_%u_%u</SdkVersion>\n" \
|
||||
" <BuildTarget>%u</BuildTarget>\n" \
|
||||
" <BuildType>Release</BuildType>\n" /* Default to Release. */ \
|
||||
"<ProgramInfo>\n")) goto end;
|
||||
|
||||
/* SdkVersion. */
|
||||
if (!programInfoAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SdkVersion", sdk_version)) goto end;
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <ToolVersion />\n" /* Impossible to get. */ \
|
||||
" <PatchToolVersion />\n" /* Impossible to get. */ \
|
||||
" <BuildTarget>%u</BuildTarget>\n", \
|
||||
is_64bit ? 64 : 32)) goto end;
|
||||
|
||||
/* BuildType. */
|
||||
if (!programInfoAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "BuildType", build_type)) goto end;
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <EnableDeadStrip />\n" /* Impossible to get. */ \
|
||||
" <Desc>%s</Desc>\n" \
|
||||
" <DescFileName />\n" /* Impossible to get. */ \
|
||||
" <DescFlags>\n" \
|
||||
" <Production>%s</Production>\n" \
|
||||
" <UnqualifiedApproval>%s</UnqualifiedApproval>\n" \
|
||||
" </DescFlags>\n" \
|
||||
" <MiddlewareList>\n", \
|
||||
sdk_addon_version->major, sdk_addon_version->minor, sdk_addon_version->micro, \
|
||||
is_64bit ? 64 : 32, \
|
||||
" </DescFlags>\n", \
|
||||
npdm_acid_b64, \
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.production ? "true" : "false", \
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.unqualified_approval ? "true" : "false")) goto end;
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.production ? g_trueString : g_falseString, \
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.unqualified_approval ? g_trueString : g_falseString)) goto end;
|
||||
|
||||
/* MiddlewareList. */
|
||||
if (!programInfoAddNsoApiListToAuthoringToolXml(&xml_buf, &xml_buf_size, program_info_ctx, "Middleware", "Module", "SDK MW")) goto end;
|
||||
|
||||
/* DebugApiList. */
|
||||
if (!programInfoAddNsoApiListToAuthoringToolXml(&xml_buf, &xml_buf_size, program_info_ctx, "DebugApi", "Api", "SDK Debug")) goto end;
|
||||
|
||||
/* PrivateApiList. */
|
||||
if (!programInfoAddNsoApiListToAuthoringToolXml(&xml_buf, &xml_buf_size, program_info_ctx, "PrivateApi", "Api", "SDK Private")) goto end;
|
||||
|
||||
/* UnresolvedApiList. Add symbols from "main" NSO. */
|
||||
if (!programInfoAddNsoSymbolsToAuthoringToolXml(&xml_buf, &xml_buf_size, program_info_ctx)) goto end;
|
||||
|
||||
/* GuidelineList. */
|
||||
if (!programInfoAddNsoApiListToAuthoringToolXml(&xml_buf, &xml_buf_size, program_info_ctx, "GuidelineApi", "Api", "SDK Guideline")) goto end;
|
||||
|
||||
|
||||
|
||||
/* Add Middleware info. */
|
||||
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
|
||||
{
|
||||
if (!programInfoAddNsoMiddlewareListToAuthoringToolXml(&xml_buf, &xml_buf_size, &(program_info_ctx->nso_ctx[i]))) goto end;
|
||||
}
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" </MiddlewareList>\n" \
|
||||
" <DebugApiList />\n" /* Fill this? */ \
|
||||
" <PrivateApiList />\n" /* Fill this? */ \
|
||||
" <UnresolvedApiList>\n")) goto end;
|
||||
|
||||
/* Add symbols from main NSO. */
|
||||
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
|
||||
{
|
||||
/* Only proceed if we're dealing with the main NSO. */
|
||||
NsoContext *nso_ctx = &(program_info_ctx->nso_ctx[i]);
|
||||
if (!nso_ctx->nso_filename || strlen(nso_ctx->nso_filename) != 4 || strcmp(nso_ctx->nso_filename, "main") != 0) continue;
|
||||
if (!programInfoAddNsoSymbolsToAuthoringToolXml(&xml_buf, &xml_buf_size, nso_ctx, is_64bit)) goto end;
|
||||
break;
|
||||
}
|
||||
|
||||
/* To do: add GuidelineApi. */
|
||||
|
||||
if (!(success = utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" </UnresolvedApiList>\n" \
|
||||
" <FsAccessControlData />\n" /* Fill this? */ \
|
||||
" <FsAccessControlData />\n" \
|
||||
" <History />\n" /* Impossible to get. */ \
|
||||
"</ProgramInfo>"))) goto end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Update ProgramInfo context. */
|
||||
program_info_ctx->authoring_tool_xml = xml_buf;
|
||||
program_info_ctx->authoring_tool_xml_size = strlen(xml_buf);
|
||||
|
@ -226,6 +252,10 @@ bool programInfoGenerateAuthoringToolXml(ProgramInfoContext *program_info_ctx)
|
|||
end:
|
||||
if (npdm_acid_b64) free(npdm_acid_b64);
|
||||
|
||||
if (build_type) free(build_type);
|
||||
|
||||
if (sdk_version) free(sdk_version);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
if (xml_buf) free(xml_buf);
|
||||
|
@ -235,66 +265,263 @@ end:
|
|||
return success;
|
||||
}
|
||||
|
||||
static bool programInfoAddNsoMiddlewareListToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const NsoContext *nso_ctx)
|
||||
static bool programInfoGetSdkVersionAndBuildTypeFromSdkNso(ProgramInfoContext *program_info_ctx, char **sdk_version, char **build_type)
|
||||
{
|
||||
if (!xml_buf || !xml_buf_size || !nso_ctx || !nso_ctx->nso_filename)
|
||||
if (!program_info_ctx || !program_info_ctx->nso_count || !program_info_ctx->nso_ctx || !sdk_version || !build_type)
|
||||
{
|
||||
LOGFILE("Invalid parameters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if this NSO holds an .api_info section. */
|
||||
/* If not, then just return right away. */
|
||||
if (!nso_ctx->rodata_api_info_section || !nso_ctx->rodata_api_info_section_size) return true;
|
||||
NsoContext *nso_ctx = NULL;
|
||||
char *sdk_entry = NULL, *sdk_entry_vender = NULL, *sdk_entry_name = NULL, *sdk_entry_version = NULL, *sdk_entry_build_type = NULL;
|
||||
size_t sdk_entry_version_len = 0;
|
||||
bool success = true;
|
||||
|
||||
/* Look for SDK Middlewares in the .api_info section from this NSO's .rodata segment. */
|
||||
/* Locate "sdk" NSO. */
|
||||
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
|
||||
{
|
||||
nso_ctx = &(program_info_ctx->nso_ctx[i]);
|
||||
if (nso_ctx->nso_filename && strlen(nso_ctx->nso_filename) == 3 && !strcmp(nso_ctx->nso_filename, "sdk") && nso_ctx->rodata_api_info_section && nso_ctx->rodata_api_info_section_size) break;
|
||||
nso_ctx = NULL;
|
||||
}
|
||||
|
||||
/* Check if we found the "sdk" NSO. */
|
||||
if (!nso_ctx) goto end;
|
||||
|
||||
/* Look for the "nnSdk" entry in .api_info section. */
|
||||
for(u64 i = 0; i < nso_ctx->rodata_api_info_section_size; i++)
|
||||
{
|
||||
if ((nso_ctx->rodata_api_info_section_size - i) <= 7) break;
|
||||
|
||||
char *sdk_mw = (nso_ctx->rodata_api_info_section + i);
|
||||
if (strncmp(sdk_mw, "SDK MW+", 7) != 0) continue;
|
||||
|
||||
/* Found a match. Let's retrieve pointers to the middleware vender and name. */
|
||||
char *sdk_mw_vender = (sdk_mw + 7);
|
||||
char *sdk_mw_name = (strchr(sdk_mw_vender, '+') + 1);
|
||||
|
||||
/* Filter nnSdk entries. */
|
||||
if (!strncasecmp(sdk_mw_name, "NintendoSdk_nnSdk", 17))
|
||||
sdk_entry = (nso_ctx->rodata_api_info_section + i);
|
||||
if (strncmp(sdk_entry, "SDK ", 4) != 0)
|
||||
{
|
||||
i += strlen(sdk_mw);
|
||||
i += strlen(sdk_entry);
|
||||
sdk_entry = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, \
|
||||
" <Middleware>\n" \
|
||||
" <ModuleName>%s</ModuleName>\n" \
|
||||
" <VenderName>%.*s</VenderName>\n" \
|
||||
" <NsoName>%s</NsoName>\n" \
|
||||
" </Middleware>\n", \
|
||||
sdk_mw_name, \
|
||||
(int)(sdk_mw_name - sdk_mw_vender - 1), sdk_mw_vender, \
|
||||
nso_ctx->nso_filename)) return false;
|
||||
sdk_entry_vender = (strchr(sdk_entry, '+') + 1);
|
||||
sdk_entry_name = (strchr(sdk_entry_vender, '+') + 1);
|
||||
|
||||
/* Update counter. */
|
||||
i += strlen(sdk_mw);
|
||||
/* Check if we're dealing with a "nnSdk" entry. */
|
||||
if (strncmp(sdk_entry_name, g_nnSdkString, strlen(g_nnSdkString)) != 0)
|
||||
{
|
||||
i += strlen(sdk_entry);
|
||||
sdk_entry = sdk_entry_vender = sdk_entry_name = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Jackpot. */
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
/* Bail out if we couldn't find the "nnSdk" entry. */
|
||||
if (!sdk_entry) goto end;
|
||||
|
||||
/* Get the SDK version and build type. */
|
||||
sdk_entry_version = (strchr(sdk_entry_name, '-') + 1);
|
||||
sdk_entry_build_type = (strchr(sdk_entry_version, '-') + 1);
|
||||
sdk_entry_version_len = (sdk_entry_build_type - sdk_entry_version - 1);
|
||||
|
||||
/* Duplicate strings. */
|
||||
if (!(*sdk_version = strndup(sdk_entry_version, sdk_entry_version_len)) || !(*build_type = strdup(sdk_entry_build_type)))
|
||||
{
|
||||
LOGFILE("Failed to allocate memory for output strings!");
|
||||
success = false;
|
||||
}
|
||||
|
||||
end:
|
||||
if (success)
|
||||
{
|
||||
/* Set output pointers to NULL if we have no usable nnSdk information. */
|
||||
if (!nso_ctx || !sdk_entry) *sdk_version = *build_type = NULL;
|
||||
} else {
|
||||
if (*sdk_version)
|
||||
{
|
||||
free(*sdk_version);
|
||||
*sdk_version = NULL;
|
||||
}
|
||||
|
||||
if (*build_type)
|
||||
{
|
||||
free(*build_type);
|
||||
*build_type = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const NsoContext *nso_ctx, bool is_64bit)
|
||||
static bool programInfoAddStringFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, const char *value)
|
||||
{
|
||||
if (!xml_buf || !xml_buf_size || !nso_ctx || !nso_ctx->nso_filename || !nso_ctx->rodata_dynstr_section || !nso_ctx->rodata_dynstr_section_size || !nso_ctx->rodata_dynsym_section || \
|
||||
!nso_ctx->rodata_dynsym_section_size)
|
||||
if (!xml_buf || !xml_buf_size || !tag_name || !strlen(tag_name))
|
||||
{
|
||||
LOGFILE("Invalid parameters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 symbol_size = (!is_64bit ? sizeof(Elf32Symbol) : sizeof(Elf64Symbol));
|
||||
return ((value && strlen(value)) ? utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%s</%s>\n", tag_name, value, tag_name) : \
|
||||
utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s />\n", tag_name));
|
||||
}
|
||||
|
||||
static bool programInfoAddNsoApiListToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, ProgramInfoContext *program_info_ctx, const char *api_list_tag, const char *api_entry_prefix, \
|
||||
const char *sdk_prefix)
|
||||
{
|
||||
size_t sdk_prefix_len = 0;
|
||||
bool success = false, api_list_exists = false;
|
||||
|
||||
/* Parse ELF dynamic symbol table to retrieve the right symbol strings. */
|
||||
if (!xml_buf || !xml_buf_size || !program_info_ctx || !program_info_ctx->nso_count || !program_info_ctx->nso_ctx || !api_list_tag || !strlen(api_list_tag) || !api_entry_prefix || \
|
||||
!strlen(api_entry_prefix) || !sdk_prefix || !(sdk_prefix_len = strlen(sdk_prefix)))
|
||||
{
|
||||
LOGFILE("Invalid parameters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if any entries for this API list exist. */
|
||||
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
|
||||
{
|
||||
NsoContext *nso_ctx = &(program_info_ctx->nso_ctx[i]);
|
||||
if (!nso_ctx->nso_filename || !strlen(nso_ctx->nso_filename) || !nso_ctx->rodata_api_info_section || !nso_ctx->rodata_api_info_section_size) continue;
|
||||
|
||||
for(u64 j = 0; j < nso_ctx->rodata_api_info_section_size; j++)
|
||||
{
|
||||
char *sdk_entry = (nso_ctx->rodata_api_info_section + j);
|
||||
if (strncmp(sdk_entry, sdk_prefix, sdk_prefix_len) != 0)
|
||||
{
|
||||
j += strlen(sdk_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *sdk_entry_vender = (strchr(sdk_entry, '+') + 1);
|
||||
char *sdk_entry_name = (strchr(sdk_entry_vender, '+') + 1);
|
||||
|
||||
/* Filter "nnSdk" entries. */
|
||||
if (!strncmp(sdk_entry_name, g_nnSdkString, strlen(g_nnSdkString)))
|
||||
{
|
||||
j += strlen(sdk_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Jackpot. */
|
||||
api_list_exists = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (api_list_exists) break;
|
||||
}
|
||||
|
||||
/* Append an empty XML element if no entries for this API list exist. */
|
||||
if (!api_list_exists)
|
||||
{
|
||||
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%sList />\n", api_list_tag);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%sList>\n", api_list_tag)) goto end;
|
||||
|
||||
/* Retrieve full API list. */
|
||||
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
|
||||
{
|
||||
NsoContext *nso_ctx = &(program_info_ctx->nso_ctx[i]);
|
||||
if (!nso_ctx->nso_filename || !strlen(nso_ctx->nso_filename) || !nso_ctx->rodata_api_info_section || !nso_ctx->rodata_api_info_section_size) continue;
|
||||
|
||||
for(u64 j = 0; j < nso_ctx->rodata_api_info_section_size; j++)
|
||||
{
|
||||
char *sdk_entry = (nso_ctx->rodata_api_info_section + j);
|
||||
if (strncmp(sdk_entry, sdk_prefix, sdk_prefix_len) != 0)
|
||||
{
|
||||
j += strlen(sdk_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *sdk_entry_vender = (strchr(sdk_entry, '+') + 1);
|
||||
char *sdk_entry_name = (strchr(sdk_entry_vender, '+') + 1);
|
||||
|
||||
/* Filter "nnSdk" entries. */
|
||||
if (!strncmp(sdk_entry_name, g_nnSdkString, strlen(g_nnSdkString)))
|
||||
{
|
||||
j += strlen(sdk_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, \
|
||||
" <%s>\n" \
|
||||
" <%sName>%s</%sName>\n" \
|
||||
" <VenderName>%.*s</VenderName>\n" \
|
||||
" <NsoName>%s</NsoName>\n" \
|
||||
" </%s>\n", \
|
||||
api_list_tag, \
|
||||
api_entry_prefix, sdk_entry_name, api_entry_prefix, \
|
||||
(int)(sdk_entry_name - sdk_entry_vender - 1), sdk_entry_vender, \
|
||||
nso_ctx->nso_filename, \
|
||||
api_list_tag)) goto end;
|
||||
|
||||
/* Update counter. */
|
||||
j += strlen(sdk_entry);
|
||||
}
|
||||
}
|
||||
|
||||
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " </%sList>\n", api_list_tag);
|
||||
|
||||
end:
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, ProgramInfoContext *program_info_ctx)
|
||||
{
|
||||
if (!xml_buf || !xml_buf_size || !program_info_ctx || !program_info_ctx->npdm_ctx.meta_header || !program_info_ctx->nso_count || !program_info_ctx->nso_ctx)
|
||||
{
|
||||
LOGFILE("Invalid parameters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
NsoContext *nso_ctx = NULL;
|
||||
bool is_64bit = (program_info_ctx->npdm_ctx.meta_header->flags.is_64bit_instruction == 1);
|
||||
u64 symbol_size = (!is_64bit ? sizeof(Elf32Symbol) : sizeof(Elf64Symbol));
|
||||
bool success = false, symbols_exist = false;
|
||||
|
||||
/* Locate "main" NSO. */
|
||||
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
|
||||
{
|
||||
nso_ctx = &(program_info_ctx->nso_ctx[i]);
|
||||
if (nso_ctx->nso_filename && strlen(nso_ctx->nso_filename) == 4 && !strcmp(nso_ctx->nso_filename, "main") && nso_ctx->rodata_dynstr_section && nso_ctx->rodata_dynstr_section_size && \
|
||||
nso_ctx->rodata_dynsym_section && nso_ctx->rodata_dynsym_section_size) break;
|
||||
nso_ctx = NULL;
|
||||
}
|
||||
|
||||
/* Check if we found the "main" NSO. */
|
||||
if (!nso_ctx) goto end;
|
||||
|
||||
/* Check if any symbols matching the required filters exist. */
|
||||
for(u64 i = 0; i < nso_ctx->rodata_dynsym_section_size; i += symbol_size)
|
||||
{
|
||||
if ((nso_ctx->rodata_dynsym_section_size - i) < symbol_size) break;
|
||||
|
||||
u8 st_type = 0;
|
||||
|
||||
/* To do: change ELF symbol filters? */
|
||||
if (!is_64bit)
|
||||
{
|
||||
/* Parse 32-bit ELF symbol. */
|
||||
Elf32Symbol *elf32_symbol = (Elf32Symbol*)(nso_ctx->rodata_dynsym_section + i);
|
||||
st_type = ELF_ST_TYPE(elf32_symbol->st_info);
|
||||
symbols_exist = (elf32_symbol->st_name < nso_ctx->rodata_dynstr_section_size && (st_type == STT_NOTYPE || st_type == STT_FUNC) && elf32_symbol->st_shndx == SHN_UNDEF);
|
||||
} else {
|
||||
/* Parse 64-bit ELF symbol. */
|
||||
Elf64Symbol *elf64_symbol = (Elf64Symbol*)(nso_ctx->rodata_dynsym_section + i);
|
||||
st_type = ELF_ST_TYPE(elf64_symbol->st_info);
|
||||
symbols_exist = (elf64_symbol->st_name < nso_ctx->rodata_dynstr_section_size && (st_type == STT_NOTYPE || st_type == STT_FUNC) && elf64_symbol->st_shndx == SHN_UNDEF);
|
||||
}
|
||||
|
||||
if (symbols_exist) break;
|
||||
}
|
||||
|
||||
/* Bail out if we couldn't find any valid symbols. */
|
||||
if (!symbols_exist) goto end;
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <UnresolvedApiList>\n")) goto end;
|
||||
|
||||
/* Parse ELF dynamic symbol table to retrieve the symbol strings. */
|
||||
for(u64 i = 0; i < nso_ctx->rodata_dynsym_section_size; i += symbol_size)
|
||||
{
|
||||
if ((nso_ctx->rodata_dynsym_section_size - i) < symbol_size) break;
|
||||
|
@ -309,15 +536,15 @@ static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_
|
|||
Elf32Symbol *elf32_symbol = (Elf32Symbol*)(nso_ctx->rodata_dynsym_section + i);
|
||||
st_type = ELF_ST_TYPE(elf32_symbol->st_info);
|
||||
|
||||
symbol_str = ((elf32_symbol->st_name < nso_ctx->rodata_dynstr_section_size && !elf32_symbol->st_value && (st_type == STT_NOTYPE || st_type == STT_FUNC) && \
|
||||
elf32_symbol->st_shndx == SHN_UNDEF) ? (nso_ctx->rodata_dynstr_section + elf32_symbol->st_name) : NULL);
|
||||
symbol_str = ((elf32_symbol->st_name < nso_ctx->rodata_dynstr_section_size && (st_type == STT_NOTYPE || st_type == STT_FUNC) && elf32_symbol->st_shndx == SHN_UNDEF) ? \
|
||||
(nso_ctx->rodata_dynstr_section + elf32_symbol->st_name) : NULL);
|
||||
} else {
|
||||
/* Parse 64-bit ELF symbol. */
|
||||
Elf64Symbol *elf64_symbol = (Elf64Symbol*)(nso_ctx->rodata_dynsym_section + i);
|
||||
st_type = ELF_ST_TYPE(elf64_symbol->st_info);
|
||||
|
||||
symbol_str = ((elf64_symbol->st_name < nso_ctx->rodata_dynstr_section_size && !elf64_symbol->st_value && (st_type == STT_NOTYPE || st_type == STT_FUNC) && \
|
||||
elf64_symbol->st_shndx == SHN_UNDEF) ? (nso_ctx->rodata_dynstr_section + elf64_symbol->st_name) : NULL);
|
||||
symbol_str = ((elf64_symbol->st_name < nso_ctx->rodata_dynstr_section_size && (st_type == STT_NOTYPE || st_type == STT_FUNC) && elf64_symbol->st_shndx == SHN_UNDEF) ? \
|
||||
(nso_ctx->rodata_dynstr_section + elf64_symbol->st_name) : NULL);
|
||||
}
|
||||
|
||||
if (!symbol_str) continue;
|
||||
|
@ -328,8 +555,14 @@ static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_
|
|||
" <NsoName>%s</NsoName>\n" \
|
||||
" </UnresolvedApi>\n", \
|
||||
symbol_str, \
|
||||
nso_ctx->nso_filename)) return false;
|
||||
nso_ctx->nso_filename)) goto end;
|
||||
}
|
||||
|
||||
return true;
|
||||
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " </UnresolvedApiList>\n");
|
||||
|
||||
end:
|
||||
/* Append an empty XML element if no valid symbols exist. */
|
||||
if (!success && (!nso_ctx || !symbols_exist)) success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <UnresolvedApiList />\n");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue