Commit 3783ffa6 authored by Ian Lynagh's avatar Ian Lynagh
Browse files

rts/Linker.c tidyups and debug belches

Part of the patch from #5062, from Greg Wright.
parent 159fdb19
......@@ -4846,10 +4846,9 @@ static int relocateSection(
// and use #ifdefs for the other types.
// Step 1: Figure out what the relocated value should be
if(scat->r_type == GENERIC_RELOC_VANILLA)
{
word = *wordPtr + (unsigned long) relocateAddress(
oc,
if (scat->r_type == GENERIC_RELOC_VANILLA) {
word = *wordPtr
+ (unsigned long) relocateAddress(oc,
nSections,
sections,
scat->r_value)
......@@ -4869,9 +4868,10 @@ static int relocateSection(
struct scattered_relocation_info *pair =
(struct scattered_relocation_info*) &relocs[i+1];
if(!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR)
if (!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR) {
barf("Invalid Mach-O file: "
"RELOC_*_SECTDIFF not followed by RELOC_PAIR");
}
word = (unsigned long)
(relocateAddress(oc, nSections, sections, scat->r_value)
......@@ -4885,9 +4885,11 @@ static int relocateSection(
|| scat->r_type == PPC_RELOC_LO14)
{ // these are generated by label+offset things
struct relocation_info *pair = &relocs[i+1];
if((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR)
if ((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR) {
barf("Invalid Mach-O file: "
"PPC_RELOC_* not followed by PPC_RELOC_PAIR");
}
if(scat->r_type == PPC_RELOC_LO16)
{
......@@ -4918,8 +4920,7 @@ static int relocateSection(
i++;
}
#endif
else
{
else {
barf ("Don't know how to handle this Mach-O "
"scattered relocation entry: "
"object file %s; entry type %ld; "
......@@ -4942,15 +4943,18 @@ static int relocateSection(
*wordPtr = word;
}
#ifdef powerpc_HOST_ARCH
else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16)
else if (scat->r_type == PPC_RELOC_LO16_SECTDIFF
|| scat->r_type == PPC_RELOC_LO16)
{
((unsigned short*) wordPtr)[1] = word & 0xFFFF;
}
else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF || scat->r_type == PPC_RELOC_HI16)
else if (scat->r_type == PPC_RELOC_HI16_SECTDIFF
|| scat->r_type == PPC_RELOC_HI16)
{
((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
}
else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF || scat->r_type == PPC_RELOC_HA16)
else if (scat->r_type == PPC_RELOC_HA16_SECTDIFF
|| scat->r_type == PPC_RELOC_HA16)
{
((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
+ ((word & (1<<15)) ? 1 : 0);
......@@ -4985,11 +4989,12 @@ static int relocateSection(
else /* !(relocs[i].r_address & R_SCATTERED) */
{
struct relocation_info *reloc = &relocs[i];
if(reloc->r_pcrel && !reloc->r_extern)
if (reloc->r_pcrel && !reloc->r_extern) {
IF_DEBUG(linker, debugBelch("relocateSection: pc relative but not external, skipping\n"));
continue;
}
if(reloc->r_length == 2)
{
if (reloc->r_length == 2) {
unsigned long word = 0;
#ifdef powerpc_HOST_ARCH
unsigned long jumpIsland = 0;
......@@ -5001,34 +5006,28 @@ static int relocateSection(
unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address);
checkProddableBlock(oc,wordPtr);
if(reloc->r_type == GENERIC_RELOC_VANILLA)
{
if (reloc->r_type == GENERIC_RELOC_VANILLA) {
word = *wordPtr;
}
#ifdef powerpc_HOST_ARCH
else if(reloc->r_type == PPC_RELOC_LO16)
{
else if (reloc->r_type == PPC_RELOC_LO16) {
word = ((unsigned short*) wordPtr)[1];
word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
}
else if(reloc->r_type == PPC_RELOC_HI16)
{
else if (reloc->r_type == PPC_RELOC_HI16) {
word = ((unsigned short*) wordPtr)[1] << 16;
word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF);
}
else if(reloc->r_type == PPC_RELOC_HA16)
{
else if (reloc->r_type == PPC_RELOC_HA16) {
word = ((unsigned short*) wordPtr)[1] << 16;
word += ((short)relocs[i+1].r_address & (short)0xFFFF);
}
else if(reloc->r_type == PPC_RELOC_BR24)
{
else if (reloc->r_type == PPC_RELOC_BR24) {
word = *wordPtr;
word = (word & 0x03FFFFFC) | ((word & 0x02000000) ? 0xFC000000 : 0);
}
#endif
else
{
else {
barf("Can't handle this Mach-O relocation entry "
"(not scattered): "
"object file %s; entry type %ld; address %#lx\n",
......@@ -5038,28 +5037,24 @@ static int relocateSection(
return 0;
}
if(!reloc->r_extern)
{
long delta =
sections[reloc->r_symbolnum-1].offset
if (!reloc->r_extern) {
long delta = sections[reloc->r_symbolnum-1].offset
- sections[reloc->r_symbolnum-1].addr
+ ((long) image);
word += delta;
}
else
{
else {
struct nlist *symbol = &nlist[reloc->r_symbolnum];
char *nm = image + symLC->stroff + symbol->n_un.n_strx;
void *symbolAddress = lookupSymbol(nm);
if(!symbolAddress)
{
if (!symbolAddress) {
errorBelch("\nunknown symbol `%s'", nm);
return 0;
}
if(reloc->r_pcrel)
{
if (reloc->r_pcrel) {
#ifdef powerpc_HOST_ARCH
// In the .o file, this should be a relative jump to NULL
// and we'll change it to a relative jump to the symbol
......@@ -5069,8 +5064,7 @@ static int relocateSection(
reloc->r_symbolnum,
(unsigned long) symbolAddress)
-> jumpIsland;
if(jumpIsland != 0)
{
if (jumpIsland != 0) {
offsetToJumpIsland = word + jumpIsland
- (((long)image) + sect->offset - sect->addr);
}
......@@ -5078,14 +5072,12 @@ static int relocateSection(
word += (unsigned long) symbolAddress
- (((long)image) + sect->offset - sect->addr);
}
else
{
else {
word += (unsigned long) symbolAddress;
}
}
if(reloc->r_type == GENERIC_RELOC_VANILLA)
{
if (reloc->r_type == GENERIC_RELOC_VANILLA) {
*wordPtr = word;
continue;
}
......@@ -5093,34 +5085,36 @@ static int relocateSection(
else if(reloc->r_type == PPC_RELOC_LO16)
{
((unsigned short*) wordPtr)[1] = word & 0xFFFF;
i++; continue;
i++;
continue;
}
else if(reloc->r_type == PPC_RELOC_HI16)
{
((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
i++; continue;
i++;
continue;
}
else if(reloc->r_type == PPC_RELOC_HA16)
{
((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
+ ((word & (1<<15)) ? 1 : 0);
i++; continue;
i++;
continue;
}
else if(reloc->r_type == PPC_RELOC_BR24)
{
if((word & 0x03) != 0)
if ((word & 0x03) != 0) {
barf("%s: unconditional relative branch with a displacement "
"which isn't a multiple of 4 bytes: %#lx",
OC_INFORMATIVE_FILENAME(oc),
word);
}
if((word & 0xFE000000) != 0xFE000000 &&
(word & 0xFE000000) != 0x00000000)
{
(word & 0xFE000000) != 0x00000000) {
// The branch offset is too large.
// Therefore, we try to use a jump island.
if(jumpIsland == 0)
{
if (jumpIsland == 0) {
barf("%s: unconditional relative branch out of range: "
"no jump island available: %#lx",
OC_INFORMATIVE_FILENAME(oc),
......@@ -5128,13 +5122,15 @@ static int relocateSection(
}
word = offsetToJumpIsland;
if((word & 0xFE000000) != 0xFE000000 &&
(word & 0xFE000000) != 0x00000000)
(word & 0xFE000000) != 0x00000000) {
barf("%s: unconditional relative branch out of range: "
"jump island out of range: %#lx",
OC_INFORMATIVE_FILENAME(oc),
word);
}
}
*wordPtr = (*wordPtr & 0xFC000003) | (word & 0x03FFFFFC);
continue;
}
......@@ -5155,11 +5151,13 @@ static int relocateSection(
}
#endif
}
IF_DEBUG(linker, debugBelch("relocateSection: done\n"));
return 1;
}
static int ocGetNames_MachO(ObjectCode* oc)
static int
ocGetNames_MachO(ObjectCode* oc)
{
char *image = (char*) oc->image;
struct mach_header *header = (struct mach_header*) image;
......@@ -5177,10 +5175,13 @@ static int ocGetNames_MachO(ObjectCode* oc)
for(i=0;i<header->ncmds;i++)
{
if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64)
if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
segLC = (struct segment_command*) lc;
else if(lc->cmd == LC_SYMTAB)
}
else if (lc->cmd == LC_SYMTAB) {
symLC = (struct symtab_command*) lc;
}
lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
}
......@@ -5188,14 +5189,19 @@ static int ocGetNames_MachO(ObjectCode* oc)
nlist = symLC ? (struct nlist*) (image + symLC->symoff)
: NULL;
if(!segLC)
if (!segLC) {
barf("ocGetNames_MachO: no segment load command");
}
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: will load %d sections\n", segLC->nsects));
for(i=0;i<segLC->nsects;i++)
{
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: segment %d\n", i));
if (sections[i].size == 0)
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: section %d\n", i));
if (sections[i].size == 0) {
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: found a zero length section, skipping\n"));
continue;
}
if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL)
{
......@@ -5204,36 +5210,47 @@ static int ocGetNames_MachO(ObjectCode* oc)
sections[i].offset = zeroFillArea - image;
}
if(!strcmp(sections[i].sectname,"__text"))
if (!strcmp(sections[i].sectname,"__text")) {
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __text section\n"));
addSection(oc, SECTIONKIND_CODE_OR_RODATA,
(void*) (image + sections[i].offset),
(void*) (image + sections[i].offset + sections[i].size));
else if(!strcmp(sections[i].sectname,"__const"))
}
else if (!strcmp(sections[i].sectname,"__const")) {
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __const section\n"));
addSection(oc, SECTIONKIND_RWDATA,
(void*) (image + sections[i].offset),
(void*) (image + sections[i].offset + sections[i].size));
else if(!strcmp(sections[i].sectname,"__data"))
}
else if (!strcmp(sections[i].sectname,"__data")) {
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __data section\n"));
addSection(oc, SECTIONKIND_RWDATA,
(void*) (image + sections[i].offset),
(void*) (image + sections[i].offset + sections[i].size));
}
else if(!strcmp(sections[i].sectname,"__bss")
|| !strcmp(sections[i].sectname,"__common"))
|| !strcmp(sections[i].sectname,"__common")) {
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __bss section\n"));
addSection(oc, SECTIONKIND_RWDATA,
(void*) (image + sections[i].offset),
(void*) (image + sections[i].offset + sections[i].size));
addProddableBlock(oc, (void*) (image + sections[i].offset),
}
addProddableBlock(oc,
(void *) (image + sections[i].offset),
sections[i].size);
}
// count external symbols defined here
oc->n_symbols = 0;
if(symLC)
{
for(i=0;i<symLC->nsyms;i++)
{
if(nlist[i].n_type & N_STAB)
if (symLC) {
for (i = 0; i < symLC->nsyms; i++) {
if (nlist[i].n_type & N_STAB) {
;
}
else if(nlist[i].n_type & N_EXT)
{
if((nlist[i].n_type & N_TYPE) == N_UNDF
......@@ -5277,19 +5294,27 @@ static int ocGetNames_MachO(ObjectCode* oc)
oc->symbols[curSymbol++] = nm;
}
}
else
{
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not external, skipping\n"));
}
}
else
{
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not defined in this section, skipping\n"));
}
}
}
commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
commonCounter = (unsigned long)commonStorage;
if(symLC)
{
for(i=0;i<symLC->nsyms;i++)
{
if (symLC) {
for (i = 0; i < symLC->nsyms; i++) {
if((nlist[i].n_type & N_TYPE) == N_UNDF
&& (nlist[i].n_type & N_EXT) && (nlist[i].n_value != 0))
{
&& (nlist[i].n_type & N_EXT)
&& (nlist[i].n_value != 0)) {
char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
unsigned long sz = nlist[i].n_value;
......@@ -5304,10 +5329,13 @@ static int ocGetNames_MachO(ObjectCode* oc)
}
}
}
IF_DEBUG(linker, debugBelch("ocGetNames_MachO: done\n"));
return 1;
}
static int ocResolve_MachO(ObjectCode* oc)
static int
ocResolve_MachO(ObjectCode* oc)
{
char *image = (char*) oc->image;
struct mach_header *header = (struct mach_header*) image;
......@@ -5322,12 +5350,19 @@ static int ocResolve_MachO(ObjectCode* oc)
IF_DEBUG(linker, debugBelch("ocResolve_MachO: start\n"));
for (i = 0; i < header->ncmds; i++)
{
if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64)
if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
segLC = (struct segment_command*) lc;
else if(lc->cmd == LC_SYMTAB)
IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a 32 or 64 bit segment load command\n"));
}
else if (lc->cmd == LC_SYMTAB) {
symLC = (struct symtab_command*) lc;
else if(lc->cmd == LC_DYSYMTAB)
IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a symbol table load command\n"));
}
else if (lc->cmd == LC_DYSYMTAB) {
dsymLC = (struct dysymtab_command*) lc;
IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a dynamic symbol table load command\n"));
}
lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
}
......@@ -5395,7 +5430,8 @@ static int ocResolve_MachO(ObjectCode* oc)
extern void* symbolsWithoutUnderscore[];
static void machoInitSymbolsWithoutUnderscore()
static void
machoInitSymbolsWithoutUnderscore(void)
{
void **p = symbolsWithoutUnderscore;
__asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");
......@@ -5423,7 +5459,8 @@ static void machoInitSymbolsWithoutUnderscore()
* Figure out by how much to shift the entire Mach-O file in memory
* when loading so that its single segment ends up 16-byte-aligned
*/
static int machoGetMisalignment( FILE * f )
static int
machoGetMisalignment( FILE * f )
{
struct mach_header header;
int misalignment;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment