Clang-format before editing.
This commit is contained in:
parent
c4e3d0903e
commit
ac33bdd031
|
@ -18,7 +18,7 @@ static char rcsid[] = "$Id$";
|
|||
#include "orig.h"
|
||||
#include "sym.h"
|
||||
|
||||
#define UBYTE(x) ((x) & BYTEMASK)
|
||||
#define UBYTE(x) ((x)&BYTEMASK)
|
||||
|
||||
static uint16_t read2(char* addr, int type)
|
||||
{
|
||||
|
@ -34,10 +34,13 @@ static uint32_t read4(char* addr, int type)
|
|||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
if (type & RELBR) {
|
||||
if (type & RELBR)
|
||||
{
|
||||
word0 = (UBYTE(addr[0]) << WIDTH) + UBYTE(addr[1]);
|
||||
word1 = (UBYTE(addr[2]) << WIDTH) + UBYTE(addr[3]);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
word0 = (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]);
|
||||
word1 = (UBYTE(addr[3]) << WIDTH) + UBYTE(addr[2]);
|
||||
}
|
||||
|
@ -61,9 +64,9 @@ static uint32_t get_vc4_valu(char* addr)
|
|||
* st<w> rd, $+o: [1110 0111 ww 1 d:5] [11111 o:27]
|
||||
*/
|
||||
|
||||
int32_t value = read4(addr+2, 0);
|
||||
int32_t value = read4(addr + 2, 0);
|
||||
value &= 0x07ffffff;
|
||||
value = value<<5>>5;
|
||||
value = value << 5 >> 5;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -75,7 +78,7 @@ static uint32_t get_vc4_valu(char* addr)
|
|||
|
||||
uint32_t value = read4(addr, RELWR);
|
||||
value &= 0x007fffff;
|
||||
value = value<<9>>9;
|
||||
value = value << 9 >> 9;
|
||||
value *= 2;
|
||||
return value;
|
||||
}
|
||||
|
@ -90,8 +93,8 @@ static uint32_t get_vc4_valu(char* addr)
|
|||
int32_t value = read4(addr, RELWR);
|
||||
int32_t lov = value & 0x007fffff;
|
||||
int32_t hiv = value & 0x0f000000;
|
||||
value = lov | (hiv>>1);
|
||||
value = value<<5>>5;
|
||||
value = lov | (hiv >> 1);
|
||||
value = value << 5 >> 5;
|
||||
value *= 2;
|
||||
return value;
|
||||
}
|
||||
|
@ -100,7 +103,7 @@ static uint32_t get_vc4_valu(char* addr)
|
|||
{
|
||||
/* lea: [1110 0101 000 d:5] [o:32] */
|
||||
|
||||
return read4(addr+2, 0);
|
||||
return read4(addr + 2, 0);
|
||||
}
|
||||
|
||||
assert(0 && "unrecognised VC4 instruction");
|
||||
|
@ -137,22 +140,20 @@ static bool is_powerpc_memory_op(uint32_t opcode)
|
|||
|
||||
static uint32_t get_powerpc_valu(char* addr, uint16_t type)
|
||||
{
|
||||
uint32_t opcode1 = read4(addr+0, type);
|
||||
uint32_t opcode2 = read4(addr+4, type);
|
||||
uint32_t opcode1 = read4(addr + 0, type);
|
||||
uint32_t opcode2 = read4(addr + 4, type);
|
||||
|
||||
if ((opcode1 & 0xfc000000) == 0x48000000)
|
||||
{
|
||||
/* branch instruction */
|
||||
return opcode1 & 0x03fffffd;
|
||||
}
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
||||
((opcode2 & 0xfc000000) == 0x60000000))
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && ((opcode2 & 0xfc000000) == 0x60000000))
|
||||
{
|
||||
/* addis / ori instruction pair */
|
||||
return ((opcode1 & 0xffff) << 16) | (opcode2 & 0xffff);
|
||||
}
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
||||
is_powerpc_memory_op(opcode2))
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && is_powerpc_memory_op(opcode2))
|
||||
{
|
||||
/* addis / memoryop instruction pair */
|
||||
uint16_t hi = opcode1 & 0xffff;
|
||||
|
@ -166,12 +167,13 @@ static uint32_t get_powerpc_valu(char* addr, uint16_t type)
|
|||
return ((hi << 16) | lo);
|
||||
}
|
||||
|
||||
fatal("Don't know how to read from PowerPC fixup on instructions 0x%08lx+0x%08lx",
|
||||
fatal(
|
||||
"Don't know how to read from PowerPC fixup on instructions 0x%08lx+0x%08lx",
|
||||
(unsigned long)opcode1, (unsigned long)opcode2);
|
||||
}
|
||||
|
||||
/* RELOPPC_LIS stores a signed 26-bit offset in the low bits. */
|
||||
static uint32_t get_lis_valu(char *addr, uint16_t type)
|
||||
static uint32_t get_lis_valu(char* addr, uint16_t type)
|
||||
{
|
||||
uint32_t valu = read4(addr, type) & 0x03ffffff;
|
||||
if (valu & 0x02000000)
|
||||
|
@ -189,7 +191,7 @@ static uint32_t get_mips_valu(char* addr)
|
|||
case 3: /* jal */
|
||||
case 29: /* jalx */
|
||||
/* Unsigned 26-bit payload. */
|
||||
value = value & ((1<<26)-1);
|
||||
value = value & ((1 << 26) - 1);
|
||||
break;
|
||||
|
||||
default: /* assume everything else is a b, there are lots */
|
||||
|
@ -209,7 +211,8 @@ static uint32_t get_mips_valu(char* addr)
|
|||
*/
|
||||
static uint32_t getvalu(char* addr, uint16_t type)
|
||||
{
|
||||
switch (type & RELSZ) {
|
||||
switch (type & RELSZ)
|
||||
{
|
||||
case RELO1:
|
||||
return UBYTE(addr[0]);
|
||||
case RELO2:
|
||||
|
@ -236,10 +239,13 @@ static void write2(uint16_t valu, char* addr, int type)
|
|||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
if (type & RELBR) {
|
||||
if (type & RELBR)
|
||||
{
|
||||
addr[0] = valu >> WIDTH;
|
||||
addr[1] = valu;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
addr[0] = valu;
|
||||
addr[1] = valu >> WIDTH;
|
||||
}
|
||||
|
@ -249,19 +255,25 @@ static void write4(uint32_t valu, char* addr, int type)
|
|||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
if (type & RELWR) {
|
||||
if (type & RELWR)
|
||||
{
|
||||
word0 = valu >> (2 * WIDTH);
|
||||
word1 = valu;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
word0 = valu;
|
||||
word1 = valu >> (2 * WIDTH);
|
||||
}
|
||||
if (type & RELBR) {
|
||||
if (type & RELBR)
|
||||
{
|
||||
addr[0] = word0 >> WIDTH;
|
||||
addr[1] = word0;
|
||||
addr[2] = word1 >> WIDTH;
|
||||
addr[3] = word1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
addr[0] = word0;
|
||||
addr[1] = word0 >> WIDTH;
|
||||
addr[2] = word1;
|
||||
|
@ -283,10 +295,10 @@ static void put_vc4_valu(char* addr, uint32_t value)
|
|||
* st<w> rd, o, (pc): [1110 0111 ww 1 d:5] [11111 o:27]
|
||||
*/
|
||||
|
||||
uint32_t v = read4(addr+2, 0);
|
||||
uint32_t v = read4(addr + 2, 0);
|
||||
v &= 0xf8000000;
|
||||
v |= value & 0x07ffffff;
|
||||
write4(v, addr+2, 0);
|
||||
write4(v, addr + 2, 0);
|
||||
}
|
||||
else if ((opcode & 0xf080) == 0x9000)
|
||||
{
|
||||
|
@ -296,7 +308,7 @@ static void put_vc4_valu(char* addr, uint32_t value)
|
|||
|
||||
uint32_t v = read4(addr, RELWR);
|
||||
v &= 0xff800000;
|
||||
v |= (value/2) & 0x007fffff;
|
||||
v |= (value / 2) & 0x007fffff;
|
||||
write4(v, addr, RELWR);
|
||||
}
|
||||
else if ((opcode & 0xf080) == 0x9080)
|
||||
|
@ -307,17 +319,17 @@ static void put_vc4_valu(char* addr, uint32_t value)
|
|||
*/
|
||||
|
||||
uint32_t v = read4(addr, RELWR);
|
||||
uint32_t lovalue = (value/2) & 0x007fffff;
|
||||
uint32_t hivalue = (value/2) & 0x07800000;
|
||||
uint32_t lovalue = (value / 2) & 0x007fffff;
|
||||
uint32_t hivalue = (value / 2) & 0x07800000;
|
||||
v &= 0xf0800000;
|
||||
v |= lovalue | (hivalue<<1);
|
||||
v |= lovalue | (hivalue << 1);
|
||||
write4(v, addr, RELWR);
|
||||
}
|
||||
else if ((opcode & 0xffe0) == 0xe500)
|
||||
{
|
||||
/* lea: [1110 0101 000 d:5] [o:32] */
|
||||
|
||||
write4(value, addr+2, 0);
|
||||
write4(value, addr + 2, 0);
|
||||
}
|
||||
else
|
||||
assert(0 && "unrecognised VC4 instruction");
|
||||
|
@ -330,8 +342,8 @@ static void put_vc4_valu(char* addr, uint32_t value)
|
|||
|
||||
static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
|
||||
{
|
||||
uint32_t opcode1 = read4(addr+0, type);
|
||||
uint32_t opcode2 = read4(addr+4, type);
|
||||
uint32_t opcode1 = read4(addr + 0, type);
|
||||
uint32_t opcode2 = read4(addr + 4, type);
|
||||
|
||||
if ((opcode1 & 0xfc000000) == 0x48000000)
|
||||
{
|
||||
|
@ -340,18 +352,16 @@ static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
|
|||
i |= value & 0x03fffffd;
|
||||
write4(i, addr, type);
|
||||
}
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
||||
((opcode2 & 0xfc000000) == 0x60000000))
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && ((opcode2 & 0xfc000000) == 0x60000000))
|
||||
{
|
||||
/* addis / ori instruction pair */
|
||||
uint16_t hi = value >> 16;
|
||||
uint16_t lo = value & 0xffff;
|
||||
|
||||
write4((opcode1 & 0xffff0000) | hi, addr+0, type);
|
||||
write4((opcode2 & 0xffff0000) | lo, addr+4, type);
|
||||
write4((opcode1 & 0xffff0000) | hi, addr + 0, type);
|
||||
write4((opcode2 & 0xffff0000) | lo, addr + 4, type);
|
||||
}
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
||||
is_powerpc_memory_op(opcode2))
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && is_powerpc_memory_op(opcode2))
|
||||
{
|
||||
/* addis / memoryop instruction pair */
|
||||
uint16_t hi = value >> 16;
|
||||
|
@ -362,12 +372,13 @@ static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
|
|||
if (lo > 0x7fff)
|
||||
hi++;
|
||||
|
||||
write4((opcode1 & 0xffff0000) | hi, addr+0, type);
|
||||
write4((opcode2 & 0xffff0000) | lo, addr+4, type);
|
||||
write4((opcode1 & 0xffff0000) | hi, addr + 0, type);
|
||||
write4((opcode2 & 0xffff0000) | lo, addr + 4, type);
|
||||
}
|
||||
|
||||
else
|
||||
fatal("Don't know how to write a PowerPC fixup to instructions 0x%08lx+0x%08lx",
|
||||
fatal(
|
||||
"Don't know how to write a PowerPC fixup to instructions 0x%08lx+0x%08lx",
|
||||
(unsigned long)opcode1, (unsigned long)opcode2);
|
||||
}
|
||||
|
||||
|
@ -413,14 +424,14 @@ static void put_mips_valu(char* addr, uint32_t value)
|
|||
case 3: /* jal */
|
||||
case 29: /* jalx */
|
||||
/* Unsigned 26-bit payload. */
|
||||
value = value & ((1<<26)-1);
|
||||
opcode = opcode & ~((1<<26)-1);
|
||||
value = value & ((1 << 26) - 1);
|
||||
opcode = opcode & ~((1 << 26) - 1);
|
||||
break;
|
||||
|
||||
default: /* assume everything else is a b, there are lots */
|
||||
/* Signed 16-bit payload. */
|
||||
value = value & ((1<<16)-1);
|
||||
opcode = opcode & ~((1<<16)-1);
|
||||
value = value & ((1 << 16) - 1);
|
||||
opcode = opcode & ~((1 << 16) - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -435,7 +446,8 @@ static void put_mips_valu(char* addr, uint32_t value)
|
|||
static putvalu(uint32_t valu, char* addr, uint16_t type)
|
||||
{
|
||||
|
||||
switch (type & RELSZ) {
|
||||
switch (type & RELSZ)
|
||||
{
|
||||
case RELO1:
|
||||
addr[0] = valu;
|
||||
break;
|
||||
|
@ -443,10 +455,10 @@ static putvalu(uint32_t valu, char* addr, uint16_t type)
|
|||
write2(valu, addr, type);
|
||||
break;
|
||||
case RELO2HI:
|
||||
write2(valu>>16, addr, type);
|
||||
write2(valu >> 16, addr, type);
|
||||
break;
|
||||
case RELO2HISAD:
|
||||
write2((valu>>16) + !!(valu&0x8000), addr, type);
|
||||
write2((valu >> 16) + !!(valu & 0x8000), addr, type);
|
||||
break;
|
||||
case RELO4:
|
||||
write4(valu, addr, type);
|
||||
|
@ -483,42 +495,47 @@ extern struct orig relorig[];
|
|||
* Second case: we must update the value by the change
|
||||
* in position of the section of local.
|
||||
*/
|
||||
static unsigned
|
||||
addrelo(relo, names, valu_out)
|
||||
struct outrelo *relo;
|
||||
struct outname *names;
|
||||
long *valu_out; /* Out variable. */
|
||||
static unsigned addrelo(relo, names, valu_out) struct outrelo* relo;
|
||||
struct outname* names;
|
||||
long* valu_out; /* Out variable. */
|
||||
{
|
||||
register struct outname *local = &names[relo->or_nami];
|
||||
register struct outname* local = &names[relo->or_nami];
|
||||
register unsigned short index = NLocals;
|
||||
register long valu = *valu_out;
|
||||
|
||||
if ((local->on_type & S_SCT)) {
|
||||
if ((local->on_type & S_SCT))
|
||||
{
|
||||
register int sectindex = (local->on_type & S_TYP) - S_MIN;
|
||||
|
||||
valu += relorig[sectindex].org_size;
|
||||
valu += outsect[sectindex].os_base;
|
||||
index += NGlobals + sectindex;
|
||||
} else {
|
||||
register struct outname *name;
|
||||
}
|
||||
else
|
||||
{
|
||||
register struct outname* name;
|
||||
extern int hash();
|
||||
extern struct outname *searchname();
|
||||
extern struct outname* searchname();
|
||||
extern unsigned indexof();
|
||||
extern struct outhead outhead;
|
||||
|
||||
name = searchname(local->on_mptr, hash(local->on_mptr));
|
||||
if (name == (struct outname *)0)
|
||||
if (name == (struct outname*)0)
|
||||
fatal("name %s not found in pass 2", local->on_mptr);
|
||||
if (ISCOMMON(name) || ISUNDEFINED(name)) {
|
||||
debug("can't relocate from %s\n",local->on_mptr,0,0,0);
|
||||
if (ISCOMMON(name) || ISUNDEFINED(name))
|
||||
{
|
||||
debug("can't relocate from %s\n", local->on_mptr, 0, 0, 0);
|
||||
index += indexof(name);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
valu += name->on_valu;
|
||||
if ((name->on_type & S_TYP) == S_ABS) {
|
||||
if ((name->on_type & S_TYP) == S_ABS)
|
||||
{
|
||||
index += NGlobals + outhead.oh_nsect;
|
||||
}
|
||||
else index += NGlobals +
|
||||
(name->on_type & S_TYP) - S_MIN;
|
||||
else
|
||||
index += NGlobals + (name->on_type & S_TYP) - S_MIN;
|
||||
}
|
||||
}
|
||||
*valu_out = valu;
|
||||
|
@ -530,12 +547,11 @@ addrelo(relo, names, valu_out)
|
|||
* which the header is pointed to by `head'. Relocation is relative to the
|
||||
* names in `names'; `relo' tells how to relocate.
|
||||
*/
|
||||
relocate(head, emit, names, relo, off)
|
||||
struct outhead *head;
|
||||
char *emit;
|
||||
struct outname names[];
|
||||
struct outrelo *relo;
|
||||
long off;
|
||||
relocate(head, emit, names, relo, off) struct outhead* head;
|
||||
char* emit;
|
||||
struct outname names[];
|
||||
struct outrelo* relo;
|
||||
long off;
|
||||
{
|
||||
long valu;
|
||||
int sectindex = relo->or_sect - S_MIN;
|
||||
|
@ -553,10 +569,13 @@ relocate(head, emit, names, relo, off)
|
|||
* - a section name
|
||||
* - the first name outside! the name table (argh)
|
||||
*/
|
||||
if (relo->or_nami < head->oh_nname) {
|
||||
if (relo->or_nami < head->oh_nname)
|
||||
{
|
||||
/* First two cases. */
|
||||
relo->or_nami = addrelo(relo, names, &valu);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Third case: it is absolute. The relocation of absolute
|
||||
* names is always 0. We only need to change the index.
|
||||
|
@ -571,7 +590,7 @@ relocate(head, emit, names, relo, off)
|
|||
* now we subtract the origin of the referencING section.
|
||||
*/
|
||||
if (relo->or_type & RELPC)
|
||||
valu -= relorig[sectindex].org_size+outsect[sectindex].os_base;
|
||||
valu -= relorig[sectindex].org_size + outsect[sectindex].os_base;
|
||||
|
||||
/*
|
||||
* Now put the value back.
|
||||
|
|
Loading…
Reference in a new issue