Skip to content

Commit

Permalink
Make a select the appropriate scenario for velf
Browse files Browse the repository at this point in the history
- The image module (.elf) no longer requires rel info completely.
- Automatically generate process_param according to process_image/image module.
- module_info alignment to 4-bytes. (So should not be encount to `vita-elf-create: elf_update(dest, ELF_C_WRITE) >= 0 failed: Layout error: overlapping sections`)
- Some tweak.
  • Loading branch information
Princess-of-Sleeping authored and d3m3vilurr committed Nov 11, 2023
1 parent 28d32b2 commit fb4b4a8
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 28 deletions.
53 changes: 42 additions & 11 deletions src/vita-elf-create/sce-elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,18 @@ static int set_module_export(vita_elf_t *ve, sce_module_exports_t *export, vita_

static int set_main_module_export(vita_elf_t *ve, sce_module_exports_t *export, sce_module_info_t *module_info, vita_export_t *export_spec, void *process_param)
{
int have_process_param = export_spec->is_process_image != 0 && export_spec->is_image_module == 0;

export->size = sizeof(sce_module_exports_raw);
export->version = 0;
export->flags = 0x8000; // for syslib
export->num_syms_funcs = (export_spec->is_image_module == 0) ? 1 : 0; // Really all modules have module_start?
export->num_syms_vars = 2; // module_info/process_param for default
export->version = 0;
export->flags = 0x8000; // for syslib
export->num_syms_funcs = 0;
export->num_syms_vars = 1; // module_info for default

if (export_spec->is_image_module == 0) {
if (export_spec->start)
++export->num_syms_funcs;

if (export_spec->bootstart)
++export->num_syms_funcs;

Expand All @@ -204,6 +209,10 @@ static int set_main_module_export(vita_elf_t *ve, sce_module_exports_t *export,
++export->num_syms_funcs;
}

if (have_process_param != 0) {
++export->num_syms_vars;
}

if (ve->module_sdk_version_ptr != 0xFFFFFFFF) {
++export->num_syms_vars;
}
Expand Down Expand Up @@ -270,9 +279,11 @@ static int set_main_module_export(vita_elf_t *ve, sce_module_exports_t *export,
export->entry_table[cur_nid] = module_info;
++cur_nid;

export->nid_table[cur_nid] = NID_PROCESS_PARAM;
export->entry_table[cur_nid] = process_param;
++cur_nid;
if (have_process_param != 0) {
export->nid_table[cur_nid] = NID_PROCESS_PARAM;
export->entry_table[cur_nid] = process_param;
++cur_nid;
}

if (ve->module_sdk_version_ptr != 0xFFFFFFFF) {
export->nid_table[cur_nid] = NID_MODULE_SDK_VERSION;
Expand Down Expand Up @@ -321,13 +332,30 @@ static void set_module_import(vita_elf_t *ve, sce_module_imports_t *import, cons
}
}

sce_module_params_t *sce_elf_module_params_create(vita_elf_t *ve, int have_libc)
sce_module_params_t *sce_elf_module_params_create(vita_elf_t *ve, vita_export_t *exports, int have_libc)
{
ASSERT(ve != NULL);
ASSERT(exports != NULL);

sce_module_params_t *params = calloc(1, sizeof(sce_module_params_t));
ASSERT(params != NULL);

params->process_param_version = ve->module_sdk_version;

if (exports->is_process_image == 0 || exports->is_image_module != 0) {

params->process_param_size = 0;

sce_process_param_v6_raw *process_param;

process_param = calloc(1, sizeof(*process_param));
ASSERT(process_param != NULL);
process_param->size = 0;
params->process_param = process_param;

return params;
}

if (params->process_param_version >= VITA_TOOLCHAIN_PROCESS_PARAM_NEW_FORMAT_VERSION) {
params->process_param_size = sizeof(sce_process_param_v6_raw);

Expand Down Expand Up @@ -579,6 +607,9 @@ void sce_elf_module_info_free(sce_module_info_t *module_info)
rela->addend = addend; \
} \
} while(0)

#define sce_module_info_alignment_value (4)

void *sce_elf_module_info_encode(
const sce_module_info_t *module_info, const vita_elf_t *ve, const sce_section_sizes_t *sizes,
vita_elf_rela_table_t *rtable, sce_module_params_t *params)
Expand Down Expand Up @@ -618,7 +649,7 @@ void *sce_elf_module_info_encode(

segment_base = ve->segments[segndx].vaddr;
start_offset = ve->segments[segndx].memsz;
start_offset = (start_offset + 0xF) & ~0xF; // align to 16 bytes
start_offset = (start_offset + (sce_module_info_alignment_value - 1)) & ~(sce_module_info_alignment_value - 1);

for (i = 0; i < ve->num_segments; i++) {
if (i == segndx)
Expand Down Expand Up @@ -784,7 +815,7 @@ void *sce_elf_module_info_encode(
process_param_raw->sce_libc_param = VADDR(sceModuleInfo_rodata) + libc_param_offset + offsetof(sce_libc_param_raw, size);
ADDRELA(&process_param_raw->sce_libc_param);
}
} else {
} else if(params->process_param_size != 0) {
FAILX("Unknown process_param size (0x%lX)", params->process_param_size);
}

Expand Down Expand Up @@ -1028,7 +1059,7 @@ int sce_elf_write_module_info(

segment_base = ve->segments[segndx].vaddr;
start_segoffset = ve->segments[segndx].memsz;
start_segoffset = (start_segoffset + 0xF) & ~0xF; // align to 16 bytes, same with `sce_elf_module_info_encode`
start_segoffset = (start_segoffset + (sce_module_info_alignment_value - 1)) & ~(sce_module_info_alignment_value - 1);
total_size += (start_segoffset - ve->segments[segndx].memsz); // add the padding size

start_vaddr = segment_base + start_segoffset;
Expand Down
7 changes: 6 additions & 1 deletion src/vita-elf-create/sce-elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,12 @@ typedef struct {
sce_libc_param_t* libc_param;
} sce_module_params_t;

sce_module_params_t *sce_elf_module_params_create(vita_elf_t *ve, int have_libc);
/**
* function: sce_elf_module_params_create
*
* Create process_param and libc_param
*/
sce_module_params_t *sce_elf_module_params_create(vita_elf_t *ve, vita_export_t *exports, int have_libc);

void sce_elf_module_params_free(sce_module_params_t *params);

Expand Down
29 changes: 16 additions & 13 deletions src/vita-elf-create/vita-elf-create.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,13 @@ int main(int argc, char *argv[])

g_log = args.log_level;

if ((ve = vita_elf_load(args.input, args.check_stub_count)) == NULL)
if (args.exports) {
exports = vita_exports_load(args.exports, args.input, 0);
if (!exports)
return EXIT_FAILURE;
}

if ((ve = vita_elf_load(args.input, args.check_stub_count, exports)) == NULL)
return EXIT_FAILURE;

/* FIXME: save original segment sizes */
Expand All @@ -506,13 +512,10 @@ int main(int argc, char *argv[])
for(idx = 0; idx < ve->num_segments; idx++)
segment_sizes[idx] = ve->segments[idx].memsz;

if (args.exports) {
exports = vita_exports_load(args.exports, args.input, 0);

if (!exports)
return EXIT_FAILURE;
}
else {
if (!vita_elf_lookup_imports(ve))
status = EXIT_FAILURE;

if (!args.exports) {
// generate a default export list
exports = vita_export_generate_default(args.input);
exports->start = args.entrypoint_funcs[0];
Expand All @@ -522,9 +525,6 @@ int main(int argc, char *argv[])
vita_elf_generate_exports(ve, exports);
}

if (!vita_elf_lookup_imports(ve))
status = EXIT_FAILURE;

if (ve->fstubs_va.count) {
TRACEF(VERBOSE, "Function stubs in sections \n");
print_stubs(ve->fstubs, ve->num_fstubs);
Expand Down Expand Up @@ -563,12 +563,15 @@ int main(int argc, char *argv[])
|| get_variable_by_symbol("sceLibcHeapUnitSize1MiB", ve, NULL)
|| get_variable_by_symbol("sceLibcHeapDetectOverrun", ve, NULL);

params = sce_elf_module_params_create(ve, have_libc);
if (exports->is_process_image == 0 || exports->is_image_module != 0) {
have_libc = 0;
}

params = sce_elf_module_params_create(ve, exports, have_libc);
if (!params)
return EXIT_FAILURE;

module_info = sce_elf_module_info_create(ve, exports, params->process_param);

if (!module_info)
return EXIT_FAILURE;

Expand Down
4 changes: 2 additions & 2 deletions src/vita-elf-create/vita-elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ static int is_valid_relsection(vita_elf_t *ve, GElf_Shdr *rel) {
return 0;
}

vita_elf_t *vita_elf_load(const char *filename, int check_stub_count)
vita_elf_t *vita_elf_load(const char *filename, int check_stub_count, vita_export_t *export)
{
vita_elf_t *ve = NULL;
GElf_Ehdr ehdr;
Expand Down Expand Up @@ -623,7 +623,7 @@ vita_elf_t *vita_elf_load(const char *filename, int check_stub_count)
if (ve->symtab == NULL)
FAILX("No symbol table in binary, perhaps stripped out");

if (ve->rela_tables == NULL)
if (ve->rela_tables == NULL && export != NULL && export->is_image_module == 0)
FAILX("No relocation sections in binary; use -Wl,-q while compiling");

if (ve->fstubs_va.count != 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/vita-elf-create/vita-elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ typedef struct vita_elf_t {
int num_segments;
} vita_elf_t;

vita_elf_t *vita_elf_load(const char *filename, int check_stub_count);
vita_elf_t *vita_elf_load(const char *filename, int check_stub_count, vita_export_t *export);
void vita_elf_free(vita_elf_t *ve);

void vita_elf_generate_exports(vita_elf_t *ve, vita_export_t *exports);
Expand Down
27 changes: 27 additions & 0 deletions src/vita-export-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,25 @@ int process_module_info(yaml_node *parent, yaml_node *child, vita_export_t *info
info->attributes = (uint16_t)attrib32;
}

else if (strcmp(key->value, "process_image") == 0) {

if (!is_scalar(child)) {
fprintf(stderr, "error: line: %zd, column: %zd, expecting process_image to be scalar, got '%s'.\n", child->position.line, child->position.column, node_type_str(child));
return -1;
}

key = &child->data.scalar;

if (strcmp(key->value, "true") == 0) {
info->is_process_image = 1;
} else if (strcmp(key->value, "false") == 0) {
info->is_process_image = 0;
} else {
fprintf(stderr, "error: line: %zd, column: %zd, Received unexpected value in process_image, got '%s'. Vaild value is \"true\" or \"false\".\n", child->position.line, child->position.column, key->value);
return -1;
}
}

else if (strcmp(key->value, "imagemodule") == 0) {

if (!is_scalar(child)) {
Expand Down Expand Up @@ -658,6 +677,14 @@ vita_export_t *vita_export_generate_default(const char *elf)
return NULL;
}

/*
* | is_process_image | is_image_module |
* | 0 | 0 | prx
* | 0 | 1 | bootimage.skprx
* | 1 | 0 | eboot.bin
* | 1 | 1 | undefined
*/
exports->is_process_image = 1;
exports->is_image_module = 0;

// we don't specify any specific symbols
Expand Down
1 change: 1 addition & 0 deletions src/vita-export.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef struct {
uint8_t ver_minor;
uint16_t attributes;
uint32_t nid;
int is_process_image;
int is_image_module;
const char *bootstart;
const char *start;
Expand Down

0 comments on commit fb4b4a8

Please sign in to comment.