Clang-format before editing.

This commit is contained in:
David Given 2018-09-14 09:28:35 +02:00
parent c4e3d0903e
commit ac33bdd031

View file

@ -18,7 +18,7 @@ static char rcsid[] = "$Id$";
#include "orig.h" #include "orig.h"
#include "sym.h" #include "sym.h"
#define UBYTE(x) ((x) & BYTEMASK) #define UBYTE(x) ((x)&BYTEMASK)
static uint16_t read2(char* addr, int type) static uint16_t read2(char* addr, int type)
{ {
@ -34,10 +34,13 @@ static uint32_t read4(char* addr, int type)
{ {
unsigned short word0, word1; unsigned short word0, word1;
if (type & RELBR) { if (type & RELBR)
{
word0 = (UBYTE(addr[0]) << WIDTH) + UBYTE(addr[1]); word0 = (UBYTE(addr[0]) << WIDTH) + UBYTE(addr[1]);
word1 = (UBYTE(addr[2]) << WIDTH) + UBYTE(addr[3]); word1 = (UBYTE(addr[2]) << WIDTH) + UBYTE(addr[3]);
} else { }
else
{
word0 = (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]); word0 = (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]);
word1 = (UBYTE(addr[3]) << WIDTH) + UBYTE(addr[2]); 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] * 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 &= 0x07ffffff;
value = value<<5>>5; value = value << 5 >> 5;
return value; return value;
} }
@ -75,7 +78,7 @@ static uint32_t get_vc4_valu(char* addr)
uint32_t value = read4(addr, RELWR); uint32_t value = read4(addr, RELWR);
value &= 0x007fffff; value &= 0x007fffff;
value = value<<9>>9; value = value << 9 >> 9;
value *= 2; value *= 2;
return value; return value;
} }
@ -90,18 +93,18 @@ static uint32_t get_vc4_valu(char* addr)
int32_t value = read4(addr, RELWR); int32_t value = read4(addr, RELWR);
int32_t lov = value & 0x007fffff; int32_t lov = value & 0x007fffff;
int32_t hiv = value & 0x0f000000; int32_t hiv = value & 0x0f000000;
value = lov | (hiv>>1); value = lov | (hiv >> 1);
value = value<<5>>5; value = value << 5 >> 5;
value *= 2; value *= 2;
return value; return value;
} }
if ((opcode & 0xffe0) == 0xe500) if ((opcode & 0xffe0) == 0xe500)
{ {
/* lea: [1110 0101 000 d:5] [o:32] */ /* lea: [1110 0101 000 d:5] [o:32] */
return read4(addr+2, 0); return read4(addr + 2, 0);
} }
assert(0 && "unrecognised VC4 instruction"); 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) static uint32_t get_powerpc_valu(char* addr, uint16_t type)
{ {
uint32_t opcode1 = read4(addr+0, type); uint32_t opcode1 = read4(addr + 0, type);
uint32_t opcode2 = read4(addr+4, type); uint32_t opcode2 = read4(addr + 4, type);
if ((opcode1 & 0xfc000000) == 0x48000000) if ((opcode1 & 0xfc000000) == 0x48000000)
{ {
/* branch instruction */ /* branch instruction */
return opcode1 & 0x03fffffd; return opcode1 & 0x03fffffd;
} }
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && ((opcode2 & 0xfc000000) == 0x60000000))
((opcode2 & 0xfc000000) == 0x60000000))
{ {
/* addis / ori instruction pair */ /* addis / ori instruction pair */
return ((opcode1 & 0xffff) << 16) | (opcode2 & 0xffff); return ((opcode1 & 0xffff) << 16) | (opcode2 & 0xffff);
} }
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && is_powerpc_memory_op(opcode2))
is_powerpc_memory_op(opcode2))
{ {
/* addis / memoryop instruction pair */ /* addis / memoryop instruction pair */
uint16_t hi = opcode1 & 0xffff; uint16_t hi = opcode1 & 0xffff;
@ -166,12 +167,13 @@ static uint32_t get_powerpc_valu(char* addr, uint16_t type)
return ((hi << 16) | lo); return ((hi << 16) | lo);
} }
fatal("Don't know how to read from PowerPC fixup on instructions 0x%08lx+0x%08lx", fatal(
(unsigned long)opcode1, (unsigned long)opcode2); "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. */ /* 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; uint32_t valu = read4(addr, type) & 0x03ffffff;
if (valu & 0x02000000) if (valu & 0x02000000)
@ -189,7 +191,7 @@ static uint32_t get_mips_valu(char* addr)
case 3: /* jal */ case 3: /* jal */
case 29: /* jalx */ case 29: /* jalx */
/* Unsigned 26-bit payload. */ /* Unsigned 26-bit payload. */
value = value & ((1<<26)-1); value = value & ((1 << 26) - 1);
break; break;
default: /* assume everything else is a b, there are lots */ default: /* assume everything else is a b, there are lots */
@ -209,37 +211,41 @@ static uint32_t get_mips_valu(char* addr)
*/ */
static uint32_t getvalu(char* addr, uint16_t type) static uint32_t getvalu(char* addr, uint16_t type)
{ {
switch (type & RELSZ) { switch (type & RELSZ)
case RELO1: {
return UBYTE(addr[0]); case RELO1:
case RELO2: return UBYTE(addr[0]);
case RELO2HI: case RELO2:
case RELO2HISAD: case RELO2HI:
return read2(addr, type); case RELO2HISAD:
case RELO4: return read2(addr, type);
return read4(addr, type); case RELO4:
case RELOPPC: return read4(addr, type);
return get_powerpc_valu(addr, type); case RELOPPC:
case RELOPPC_LIS: return get_powerpc_valu(addr, type);
return get_lis_valu(addr, type); case RELOPPC_LIS:
case RELOVC4: return get_lis_valu(addr, type);
return get_vc4_valu(addr); case RELOVC4:
case RELOMIPS: return get_vc4_valu(addr);
return get_mips_valu(addr); case RELOMIPS:
default: return get_mips_valu(addr);
fatal("can't read relocation type %x", type & RELSZ); default:
fatal("can't read relocation type %x", type & RELSZ);
} }
/* NOTREACHED */ /* NOTREACHED */
} }
static void write2(uint16_t valu, char* addr, int type) static void write2(uint16_t valu, char* addr, int type)
{ {
unsigned short word0, word1; unsigned short word0, word1;
if (type & RELBR) { if (type & RELBR)
{
addr[0] = valu >> WIDTH; addr[0] = valu >> WIDTH;
addr[1] = valu; addr[1] = valu;
} else { }
else
{
addr[0] = valu; addr[0] = valu;
addr[1] = valu >> WIDTH; addr[1] = valu >> WIDTH;
} }
@ -247,21 +253,27 @@ static void write2(uint16_t valu, char* addr, int type)
static void write4(uint32_t valu, char* addr, int type) static void write4(uint32_t valu, char* addr, int type)
{ {
unsigned short word0, word1; unsigned short word0, word1;
if (type & RELWR) { if (type & RELWR)
{
word0 = valu >> (2 * WIDTH); word0 = valu >> (2 * WIDTH);
word1 = valu; word1 = valu;
} else { }
else
{
word0 = valu; word0 = valu;
word1 = valu >> (2 * WIDTH); word1 = valu >> (2 * WIDTH);
} }
if (type & RELBR) { if (type & RELBR)
{
addr[0] = word0 >> WIDTH; addr[0] = word0 >> WIDTH;
addr[1] = word0; addr[1] = word0;
addr[2] = word1 >> WIDTH; addr[2] = word1 >> WIDTH;
addr[3] = word1; addr[3] = word1;
} else { }
else
{
addr[0] = word0; addr[0] = word0;
addr[1] = word0 >> WIDTH; addr[1] = word0 >> WIDTH;
addr[2] = word1; 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] * 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 &= 0xf8000000;
v |= value & 0x07ffffff; v |= value & 0x07ffffff;
write4(v, addr+2, 0); write4(v, addr + 2, 0);
} }
else if ((opcode & 0xf080) == 0x9000) 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); uint32_t v = read4(addr, RELWR);
v &= 0xff800000; v &= 0xff800000;
v |= (value/2) & 0x007fffff; v |= (value / 2) & 0x007fffff;
write4(v, addr, RELWR); write4(v, addr, RELWR);
} }
else if ((opcode & 0xf080) == 0x9080) else if ((opcode & 0xf080) == 0x9080)
@ -307,19 +319,19 @@ static void put_vc4_valu(char* addr, uint32_t value)
*/ */
uint32_t v = read4(addr, RELWR); uint32_t v = read4(addr, RELWR);
uint32_t lovalue = (value/2) & 0x007fffff; uint32_t lovalue = (value / 2) & 0x007fffff;
uint32_t hivalue = (value/2) & 0x07800000; uint32_t hivalue = (value / 2) & 0x07800000;
v &= 0xf0800000; v &= 0xf0800000;
v |= lovalue | (hivalue<<1); v |= lovalue | (hivalue << 1);
write4(v, addr, RELWR); write4(v, addr, RELWR);
} }
else if ((opcode & 0xffe0) == 0xe500) else if ((opcode & 0xffe0) == 0xe500)
{ {
/* lea: [1110 0101 000 d:5] [o:32] */ /* lea: [1110 0101 000 d:5] [o:32] */
write4(value, addr+2, 0); write4(value, addr + 2, 0);
} }
else else
assert(0 && "unrecognised VC4 instruction"); 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) static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
{ {
uint32_t opcode1 = read4(addr+0, type); uint32_t opcode1 = read4(addr + 0, type);
uint32_t opcode2 = read4(addr+4, type); uint32_t opcode2 = read4(addr + 4, type);
if ((opcode1 & 0xfc000000) == 0x48000000) if ((opcode1 & 0xfc000000) == 0x48000000)
{ {
@ -340,18 +352,16 @@ static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
i |= value & 0x03fffffd; i |= value & 0x03fffffd;
write4(i, addr, type); write4(i, addr, type);
} }
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && ((opcode2 & 0xfc000000) == 0x60000000))
((opcode2 & 0xfc000000) == 0x60000000))
{ {
/* addis / ori instruction pair */ /* addis / ori instruction pair */
uint16_t hi = value >> 16; uint16_t hi = value >> 16;
uint16_t lo = value & 0xffff; uint16_t lo = value & 0xffff;
write4((opcode1 & 0xffff0000) | hi, addr+0, type); write4((opcode1 & 0xffff0000) | hi, addr + 0, type);
write4((opcode2 & 0xffff0000) | lo, addr+4, type); write4((opcode2 & 0xffff0000) | lo, addr + 4, type);
} }
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && is_powerpc_memory_op(opcode2))
is_powerpc_memory_op(opcode2))
{ {
/* addis / memoryop instruction pair */ /* addis / memoryop instruction pair */
uint16_t hi = value >> 16; uint16_t hi = value >> 16;
@ -362,13 +372,14 @@ static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
if (lo > 0x7fff) if (lo > 0x7fff)
hi++; hi++;
write4((opcode1 & 0xffff0000) | hi, addr+0, type); write4((opcode1 & 0xffff0000) | hi, addr + 0, type);
write4((opcode2 & 0xffff0000) | lo, addr+4, type); write4((opcode2 & 0xffff0000) | lo, addr + 4, type);
} }
else else
fatal("Don't know how to write a PowerPC fixup to instructions 0x%08lx+0x%08lx", fatal(
(unsigned long)opcode1, (unsigned long)opcode2); "Don't know how to write a PowerPC fixup to instructions 0x%08lx+0x%08lx",
(unsigned long)opcode1, (unsigned long)opcode2);
} }
/* Writes a PowerPC lis instruction. */ /* Writes a PowerPC lis instruction. */
@ -413,14 +424,14 @@ static void put_mips_valu(char* addr, uint32_t value)
case 3: /* jal */ case 3: /* jal */
case 29: /* jalx */ case 29: /* jalx */
/* Unsigned 26-bit payload. */ /* Unsigned 26-bit payload. */
value = value & ((1<<26)-1); value = value & ((1 << 26) - 1);
opcode = opcode & ~((1<<26)-1); opcode = opcode & ~((1 << 26) - 1);
break; break;
default: /* assume everything else is a b, there are lots */ default: /* assume everything else is a b, there are lots */
/* Signed 16-bit payload. */ /* Signed 16-bit payload. */
value = value & ((1<<16)-1); value = value & ((1 << 16) - 1);
opcode = opcode & ~((1<<16)-1); opcode = opcode & ~((1 << 16) - 1);
break; break;
} }
@ -435,41 +446,42 @@ static void put_mips_valu(char* addr, uint32_t value)
static putvalu(uint32_t valu, char* addr, uint16_t type) static putvalu(uint32_t valu, char* addr, uint16_t type)
{ {
switch (type & RELSZ) { switch (type & RELSZ)
case RELO1: {
addr[0] = valu; case RELO1:
break; addr[0] = valu;
case RELO2: break;
write2(valu, addr, type); case RELO2:
break; write2(valu, addr, type);
case RELO2HI: break;
write2(valu>>16, addr, type); case RELO2HI:
break; write2(valu >> 16, addr, type);
case RELO2HISAD: break;
write2((valu>>16) + !!(valu&0x8000), addr, type); case RELO2HISAD:
break; write2((valu >> 16) + !!(valu & 0x8000), addr, type);
case RELO4: break;
write4(valu, addr, type); case RELO4:
break; write4(valu, addr, type);
case RELOPPC: break;
put_powerpc_valu(addr, valu, type); case RELOPPC:
break; put_powerpc_valu(addr, valu, type);
case RELOPPC_LIS: break;
put_lis_valu(addr, valu, type); case RELOPPC_LIS:
break; put_lis_valu(addr, valu, type);
case RELOVC4: break;
put_vc4_valu(addr, valu); case RELOVC4:
break; put_vc4_valu(addr, valu);
case RELOMIPS: break;
put_mips_valu(addr, valu); case RELOMIPS:
break; put_mips_valu(addr, valu);
default: break;
fatal("can't write relocation type %x", type & RELSZ); default:
fatal("can't write relocation type %x", type & RELSZ);
} }
} }
extern struct outsect outsect[]; extern struct outsect outsect[];
extern struct orig relorig[]; extern struct orig relorig[];
/* /*
* There are two cases: `local' is an undefined external or common name, * There are two cases: `local' is an undefined external or common name,
@ -483,42 +495,47 @@ extern struct orig relorig[];
* Second case: we must update the value by the change * Second case: we must update the value by the change
* in position of the section of local. * in position of the section of local.
*/ */
static unsigned static unsigned addrelo(relo, names, valu_out) struct outrelo* relo;
addrelo(relo, names, valu_out) struct outname* names;
struct outrelo *relo; long* valu_out; /* Out variable. */
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 unsigned short index = NLocals;
register long valu = *valu_out; 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; {
register int sectindex = (local->on_type & S_TYP) - S_MIN;
valu += relorig[sectindex].org_size; valu += relorig[sectindex].org_size;
valu += outsect[sectindex].os_base; valu += outsect[sectindex].os_base;
index += NGlobals + sectindex; index += NGlobals + sectindex;
} else { }
register struct outname *name; else
extern int hash(); {
extern struct outname *searchname(); register struct outname* name;
extern unsigned indexof(); extern int hash();
extern struct outhead outhead; extern struct outname* searchname();
extern unsigned indexof();
extern struct outhead outhead;
name = searchname(local->on_mptr, hash(local->on_mptr)); 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); fatal("name %s not found in pass 2", local->on_mptr);
if (ISCOMMON(name) || ISUNDEFINED(name)) { if (ISCOMMON(name) || ISUNDEFINED(name))
debug("can't relocate from %s\n",local->on_mptr,0,0,0); {
debug("can't relocate from %s\n", local->on_mptr, 0, 0, 0);
index += indexof(name); index += indexof(name);
} else { }
else
{
valu += name->on_valu; 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; index += NGlobals + outhead.oh_nsect;
} }
else index += NGlobals + else
(name->on_type & S_TYP) - S_MIN; index += NGlobals + (name->on_type & S_TYP) - S_MIN;
} }
} }
*valu_out = valu; *valu_out = valu;
@ -530,16 +547,15 @@ addrelo(relo, names, valu_out)
* which the header is pointed to by `head'. Relocation is relative to the * which the header is pointed to by `head'. Relocation is relative to the
* names in `names'; `relo' tells how to relocate. * names in `names'; `relo' tells how to relocate.
*/ */
relocate(head, emit, names, relo, off) relocate(head, emit, names, relo, off) struct outhead* head;
struct outhead *head; char* emit;
char *emit; struct outname names[];
struct outname names[]; struct outrelo* relo;
struct outrelo *relo; long off;
long off;
{ {
long valu; long valu;
int sectindex = relo->or_sect - S_MIN; int sectindex = relo->or_sect - S_MIN;
extern struct outhead outhead; extern struct outhead outhead;
/* /*
* Pick up previous value at location to be relocated. * Pick up previous value at location to be relocated.
@ -553,10 +569,13 @@ relocate(head, emit, names, relo, off)
* - a section name * - a section name
* - the first name outside! the name table (argh) * - 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. */ /* First two cases. */
relo->or_nami = addrelo(relo, names, &valu); relo->or_nami = addrelo(relo, names, &valu);
} else { }
else
{
/* /*
* Third case: it is absolute. The relocation of absolute * Third case: it is absolute. The relocation of absolute
* names is always 0. We only need to change the index. * 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. * now we subtract the origin of the referencING section.
*/ */
if (relo->or_type & RELPC) 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. * Now put the value back.