switch(rel->r_type)
{
- case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset & 0xffff);
+ case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);
break;
- case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
+ case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);
break;
- case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
+ case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) + (int16_t)(other_half & 0xffff);
break;
case PPC_RELOC_BR24:
sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
/* Now transform the symtab, to an extended version, with the sym size, and the C name */
for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
- const char *name;
struct nlist *sym_follow, *sym_next = 0;
unsigned int j;
- name = find_str_by_index(sym->n_un.n_strx);
memset(sym, 0, sizeof(*sym));
- if ( sym->n_type & N_STAB ) /* Debug symbols are skipped */
+ if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
continue;
memcpy(sym, syment, sizeof(*syment));
#endif /* CONFIG_FORMAT_MACH */
+void get_reloc_expr(char *name, int name_size, const char *sym_name)
+{
+ const char *p;
+
+ if (strstart(sym_name, "__op_param", &p)) {
+ snprintf(name, name_size, "param%s", p);
+ } else if (strstart(sym_name, "__op_gen_label", &p)) {
+ snprintf(name, name_size, "gen_labels[param%s]", p);
+ } else {
+#ifdef HOST_SPARC
+ if (sym_name[0] == '.')
+ snprintf(name, sizeof(name),
+ "(long)(&__dot_%s)",
+ sym_name + 1);
+ else
+#endif
+ snprintf(name, name_size, "(long)(&%s)", sym_name);
+ }
+}
+
#ifdef HOST_ARM
int arm_emit_ldr_info(const char *name, unsigned long start_offset,
if (rel->r_offset == (pc_offset + start_offset)) {
sym_name = get_rel_sym_name(rel);
/* the compiler leave some unnecessary references to the code */
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(relname, sizeof(relname), "param%s", p);
- } else {
- snprintf(relname, sizeof(relname), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(relname, sizeof(relname), sym_name);
type = ELF32_R_TYPE(rel->r_info);
if (type != R_ARM_ABS32)
error("%s: unsupported data relocation", name);
continue;
}
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else if (strstart(sym_name, "__op_gen_label", &p)) {
- snprintf(name, sizeof(name), "gen_labels[param%s]", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
addend = get32((uint32_t *)(text + rel->r_offset));
#ifdef CONFIG_FORMAT_ELF
type = ELF32_R_TYPE(rel->r_info);
if (rel->r_offset >= start_offset &&
rel->r_offset < start_offset + copy_size) {
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
switch(type) {
continue;
}
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
switch(type) {
continue; /* dunno how to handle without final_sym_name */
}
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(final_sym_name, sizeof(final_sym_name), "param%s", p);
- } else {
- snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name);
- }
-
+ get_reloc_expr(final_sym_name, sizeof(final_sym_name),
+ sym_name);
switch(type) {
case PPC_RELOC_BR24:
- fprintf(outfile, "{\n");
- fprintf(outfile, " uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
+ if (!strstart(sym_name,"__op_gen_label",&p)) {
+ fprintf(outfile, "{\n");
+ fprintf(outfile, " uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
slide, slide, name, sslide );
- fprintf(outfile, "}\n");
+ fprintf(outfile, "}\n");
+ } else {
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | (((long)%s - (long)gen_code_ptr - %d) & 0x03fffffc);\n",
+ slide, slide, final_sym_name, slide);
+ }
break;
case PPC_RELOC_HI16:
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n",
if (rel->r_offset >= start_offset &&
rel->r_offset < start_offset + copy_size) {
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
switch(type) {
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF64_R_TYPE(rel->r_info);
addend = rel->r_addend;
switch(type) {
if (rel->r_offset >= start_offset &&
rel->r_offset < start_offset + copy_size) {
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- if (sym_name[0] == '.')
- snprintf(name, sizeof(name),
- "(long)(&__dot_%s)",
- sym_name + 1);
- else
- snprintf(name, sizeof(name),
- "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
switch(type) {
if (rel->r_offset >= start_offset &&
rel->r_offset < start_offset + copy_size) {
sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF64_R_TYPE(rel->r_info);
addend = rel->r_addend;
switch(type) {
/* the compiler leave some unnecessary references to the code */
if (sym_name[0] == '\0')
continue;
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = get32((uint32_t *)(text + rel->r_offset));
switch(type) {
rel->r_offset < start_offset + copy_size) {
sym = &(symtab[ELFW(R_SYM)(rel->r_info)]);
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, sizeof(name), "param%s", p);
- } else {
- snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
- }
+ get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;
switch(type) {