/*report_at (__FILE__, __LINE__, REPORT_FATAL_ERROR, "symbol: %s, %lx", symbol->name, ((rel->symbolnum) >> 28));*/
- if (((rel->symbolnum >> 27) & 1) || ((rel->symbolnum >> rel->n_type) & 0xff) != 2) {
+ if (((rel->symbolnum >> 27) & 1) || rel->n_type != 2) {
report_at (program_name, 0, REPORT_ERROR, "%s:(%s+%#lu): segment relocation", part->of->filename, part->section->name, offset);
}
int is_section = (xstrcasecmp (symbol->name, ".text") == 0) || (xstrcasecmp (symbol->name, ".data") == 0) || (xstrcasecmp (symbol->name, ".bss") == 0);
- if (is_section || (((rel->symbolnum >> rel->n_type) & 0xff) != 4 && ((rel->symbolnum >> rel->n_type) & 0xff) != 6 && ((rel->symbolnum >> rel->n_type) & 0xff) != 8)) {
+ if (is_section || (rel->n_type != 4 && rel->n_type != 6 && rel->n_type != 8)) {
if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) {
rel->howto = &reloc_howtos[RELOC_TYPE_PC64];
}
- if (xstrcasecmp (symbol->name, "DGROUP__edata") == 0 || xstrcasecmp (symbol->name, "DGROUP__end") == 0 || xstrcasecmp (symbol->name, "__etext") == 0 || xstrcasecmp (symbol->name, "__edata") == 0 || xstrcasecmp (symbol->name, "__end") == 0) {
+ if (strcasecmp (symbol->name, "DGROUP__edata") == 0 || xstrcasecmp (symbol->name, "DGROUP__end") == 0 || xstrcasecmp (symbol->name, "__etext") == 0 || xstrcasecmp (symbol->name, "__edata") == 0 || xstrcasecmp (symbol->name, "__end") == 0) {
if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) {
rel->howto = &reloc_howtos[RELOC_TYPE_PC64];
result >>= rel->howto->final_right_shift;
- if (opcode == 0xff || opcode == 0x9A) {
+ /*printf ("%lx\n", n_type);*/
- if (result >= 65535) {
+ if (opcode == 0xFF || opcode == 0x9A || rel->n_type == 0x04) {
+
+ /*printf ("%lx\n", (rel->symbolnum >> rel->n_type) & 0xff);*/
+
+ unsigned char *p = part->content + offset;
- /*report_at (program_name, 0, REPORT_ERROR, "%s:(%s+%#lu): call exceeds 65535 bytes", part->of->filename, part->section->name, offset);*/
+ if ((opcode != 0x9A && opcode != 0xFF) || result >= 65535) {
+
+ if (opcode == 0x9A || opcode == 0xFF) {
- if (rel->howto == &reloc_howtos[RELOC_TYPE_PC64]) {
- rel->howto = &reloc_howtos[RELOC_TYPE_64];
- } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC32]) {
- rel->howto = &reloc_howtos[RELOC_TYPE_32];
- } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC16]) {
- rel->howto = &reloc_howtos[RELOC_TYPE_16];
- } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC8]) {
- rel->howto = &reloc_howtos[RELOC_TYPE_8];
- }
+ *(p - 1) = 0x9A;
- result = (((unsigned long) result / 16) << 16) | (unsigned long) result % 16;
+ if (rel->howto == &reloc_howtos[RELOC_TYPE_PC64]) {
+ rel->howto = &reloc_howtos[RELOC_TYPE_64];
+ } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC32]) {
+ rel->howto = &reloc_howtos[RELOC_TYPE_32];
+ } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC16]) {
+ rel->howto = &reloc_howtos[RELOC_TYPE_16];
+ } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC8]) {
+ rel->howto = &reloc_howtos[RELOC_TYPE_8];
+ }
+
+ result = (((unsigned long) result / 16) << 16) | (unsigned long) result % 16;
+
+ /*if (opcode != 0x9A && opcode != 0xFF) {
+ printf ("%x, %lx, %lx, %lx\n", rel->n_type, part->rva + offset + 0x30, result, size);
+ }*/
+
+ while (rel->howto->size > 2) {
+
+ rel->howto->size--;
+ rel->offset++;
+
+ }
+
+ }
} else {
- unsigned char *p = part->content + offset;
+ /*printf ("%x, %lx, %lx, %lx\n", rel->n_type, part->rva + offset + 0x30, result, size);*/
if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) {
rel->howto = &reloc_howtos[RELOC_TYPE_PC64];
rel->howto = &reloc_howtos[RELOC_TYPE_PC8];
}
- *(p - 1) = 0x0E;
- *(p + 0) = 0xE8;
- *(p + 3) = 0x90;
+ if (opcode == 0x9A) {
- result -= part->rva + offset;
- result -= size;
+ *(p - 1) = 0x0E;
+ *(p + 0) = 0xE8;
+ *(p + 3) = 0x90;
+
+ result -= part->rva + offset;
+ result -= size;
+
+ while (size > 2) {
+ size--;
+ }
+
+ offset++;
+ result++;
- while (size > 2) {
+ } else {
- size--;
- /*result--;*/
+ *(p - 1) = 0x0E;
+ *(p + 0) = 0x3E;
+ *(p + 1) = 0xE8;
+
+ result -= part->rva + offset;
+ result -= size;
+
+ while (size > 2) {
+
+ offset++;
+ size--;
+
+ }
}
-
- offset++;
- result++;
}
- } else {
+ } else if (opcode != 0xE8 && rel->n_type != 0x04) {
/*if (!rel->howto->pc_rel && !rel->howto->no_base) {*/
/*if (!((rel->symbolnum >> rel->n_ext) & 1) || symbol->section_number == ABSOLUTE_SECTION_NUMBER) {*/
- if (has_dgroup/* && ((rel->symbolnum >> rel->n_type) & 0xff) != N_ABS*/) {
+ if (has_dgroup/* && rel->n_type != N_ABS*/) {
- if (xstrcasecmp (symbol->name, "__etext") != 0 && xstrcasecmp (symbol->name, "__edata") != 0 && xstrcasecmp (symbol->name, "__end") != 0) {
+ if (xstrcasecmp (symbol->name, "DGROUP__edata") != 0 && xstrcasecmp (symbol->name, "DGROUP__end") != 0 && xstrcasecmp (symbol->name, "__etext") != 0 && xstrcasecmp (symbol->name, "__edata") != 0 && xstrcasecmp (symbol->name, "__end") != 0) {
if (result >= dgroup_start) {
result -= (dgroup_start & 0xfffffff0);
+ /*printf ("%lx, %lx, %lx\n", part->rva + offset + 0x30, result, dgroup_start);*/
}
}
}
- /*} else if (result >= dgroup_start && ((rel->symbolnum >> rel->n_type) & 0xff) != N_ABS) {
+ /*} else if (result >= dgroup_start && rel->n_type != 2) {
printf ("%x, %lx, %lx, %lx\n", opcode, part->rva + offset + 0x30, result, dgroup_start);
}*/
+
+ /*printf ("%lx, %lx, %lx, %lx\n", (rel->symbolnum >> rel->n_type) & 0xff, part->rva + offset + 0x30, result, dgroup_start);*/
}
}
of = object_file_make (FAKE_LD_FILENAME, 1);
+ value -= (dgroup_start & 0xfffffff0);
symbol = of->symbol_arr;
symbol->name = xstrdup ("DGROUP__edata");
if ((symbol = symbol_find ("DGROUP__end")) && symbol_is_undefined (symbol)) {
- if ((section = section_find (".text"))) {
- value += align_section_if_needed (section->total_size);
- }
-
if ((section = section_find (".data"))) {
value += align_section_if_needed (section->total_size);
}