mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 09:21:13 +00:00
Handle multiple functions, properly mangle symbols, and fix support for
scattered relocations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33555 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ea516cce65
commit
6635f35cae
@ -307,16 +307,25 @@ namespace llvm {
|
||||
uint8_t r_length; // length = 2 ^ r_length
|
||||
bool r_extern; //
|
||||
uint8_t r_type; // if not 0, machine-specific relocation type.
|
||||
bool r_scattered; // 1 = scattered, 0 = non-scattered
|
||||
int32_t r_value; // the value the item to be relocated is referring
|
||||
// to.
|
||||
|
||||
uint32_t getPackedFields() {
|
||||
return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
|
||||
(r_extern << 4) | (r_type & 15);
|
||||
uint32_t getPackedFields() {
|
||||
if (r_scattered)
|
||||
return (1 << 31) | (r_pcrel << 30) | ((r_length & 3) << 28) |
|
||||
((r_type & 15) << 24) | (r_address & 0x00FFFFFF);
|
||||
else
|
||||
return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
|
||||
(r_extern << 4) | (r_type & 15);
|
||||
}
|
||||
uint32_t getAddress() { return r_scattered ? r_value : r_address; }
|
||||
|
||||
MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len,
|
||||
bool ext, uint8_t type) : r_address(addr),
|
||||
r_symbolnum(index), r_pcrel(pcrel), r_length(len), r_extern(ext),
|
||||
r_type(type) {}
|
||||
bool ext, uint8_t type, bool scattered = false,
|
||||
int32_t value = 0) :
|
||||
r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len),
|
||||
r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) {}
|
||||
};
|
||||
|
||||
/// MachOSection - This struct contains information about each section in a
|
||||
@ -621,7 +630,7 @@ namespace llvm {
|
||||
return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
|
||||
}
|
||||
virtual void GetTargetRelocation(MachineRelocation &MR, MachOSection &From,
|
||||
MachOSection &To) = 0;
|
||||
MachOSection &To, bool Scattered) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,15 @@ void MachOCodeEmitter::startFunction(MachineFunction &F) {
|
||||
BufferBegin = &MOS->SectionData[0];
|
||||
BufferEnd = BufferBegin + MOS->SectionData.capacity();
|
||||
|
||||
// Upgrade the section alignment if required.
|
||||
if (MOS->align < Align) MOS->align = Align;
|
||||
|
||||
// Round the size up to the correct alignment for starting the new function.
|
||||
if ((MOS->size & ((1 << Align) - 1)) != 0) {
|
||||
MOS->size += (1 << Align);
|
||||
MOS->size &= ~((1 << Align) - 1);
|
||||
}
|
||||
|
||||
// FIXME: Using MOS->size directly here instead of calculating it from the
|
||||
// output buffer size (impossible because the code emitter deals only in raw
|
||||
// bytes) forces us to manually synchronize size and write padding zero bytes
|
||||
@ -154,9 +163,6 @@ void MachOCodeEmitter::startFunction(MachineFunction &F) {
|
||||
// AddSymbolToSection to prevent calling it on the text section.
|
||||
CurBufferPtr = BufferBegin + MOS->size;
|
||||
|
||||
// Upgrade the section alignment if required.
|
||||
if (MOS->align < Align) MOS->align = Align;
|
||||
|
||||
// Clear per-function data structures.
|
||||
CPLocations.clear();
|
||||
CPSections.clear();
|
||||
@ -170,12 +176,15 @@ bool MachOCodeEmitter::finishFunction(MachineFunction &F) {
|
||||
// Get the Mach-O Section that this function belongs in.
|
||||
MachOWriter::MachOSection *MOS = MOW.getTextSection();
|
||||
|
||||
MOS->size += CurBufferPtr - BufferBegin;
|
||||
|
||||
// Get a symbol for the function to add to the symbol table
|
||||
// FIXME: it seems like we should call something like AddSymbolToSection
|
||||
// in startFunction rather than changing the section size and symbol n_value
|
||||
// here.
|
||||
const GlobalValue *FuncV = F.getFunction();
|
||||
MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TM);
|
||||
|
||||
FnSym.n_value = MOS->size;
|
||||
MOS->size = CurBufferPtr - BufferBegin;
|
||||
|
||||
// Emit constant pool to appropriate section(s)
|
||||
emitConstantPool(F.getConstantPool());
|
||||
|
||||
@ -635,6 +644,7 @@ void MachOWriter::BufferSymbolAndStringTable() {
|
||||
if (PartitionByLocal(*I)) {
|
||||
++DySymTab.nlocalsym;
|
||||
++DySymTab.iextdefsym;
|
||||
++DySymTab.iundefsym;
|
||||
} else if (PartitionByDefined(*I)) {
|
||||
++DySymTab.nextdefsym;
|
||||
++DySymTab.iundefsym;
|
||||
@ -692,6 +702,10 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) {
|
||||
for (unsigned i = 0, e = MOS.Relocations.size(); i != e; ++i) {
|
||||
MachineRelocation &MR = MOS.Relocations[i];
|
||||
unsigned TargetSection = MR.getConstantVal();
|
||||
|
||||
// This is a scattered relocation entry if it points to a global value with
|
||||
// a non-zero offset.
|
||||
bool Scattered = false;
|
||||
|
||||
// Since we may not have seen the GlobalValue we were interested in yet at
|
||||
// the time we emitted the relocation for it, fix it up now so that it
|
||||
@ -699,15 +713,16 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) {
|
||||
if (MR.isGlobalValue()) {
|
||||
GlobalValue *GV = MR.getGlobalValue();
|
||||
MachOSection *MOSPtr = GVSection[GV];
|
||||
intptr_t offset = GVOffset[GV];
|
||||
intptr_t Offset = GVOffset[GV];
|
||||
Scattered = TargetSection != 0;
|
||||
|
||||
assert(MOSPtr && "Trying to relocate unknown global!");
|
||||
|
||||
TargetSection = MOSPtr->Index;
|
||||
MR.setResultPointer((void*)offset);
|
||||
MR.setResultPointer((void*)Offset);
|
||||
}
|
||||
|
||||
GetTargetRelocation(MR, MOS, *SectionList[TargetSection-1]);
|
||||
GetTargetRelocation(MR, MOS, *SectionList[TargetSection-1], Scattered);
|
||||
}
|
||||
}
|
||||
|
||||
@ -721,6 +736,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
|
||||
|
||||
WorkList.push_back(CPair(C,(intptr_t)Addr + Offset));
|
||||
|
||||
intptr_t ScatteredOffset = 0;
|
||||
|
||||
while (!WorkList.empty()) {
|
||||
const Constant *PC = WorkList.back().first;
|
||||
intptr_t PA = WorkList.back().second;
|
||||
@ -737,7 +754,13 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
|
||||
// FIXME: Handle ConstantExpression. See EE::getConstantValue()
|
||||
//
|
||||
switch (CE->getOpcode()) {
|
||||
case Instruction::GetElementPtr:
|
||||
case Instruction::GetElementPtr: {
|
||||
std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end());
|
||||
ScatteredOffset = TD->getIndexedOffset(CE->getOperand(0)->getType(),
|
||||
Indexes);
|
||||
WorkList.push_back(CPair(CE->getOperand(0), PA));
|
||||
break;
|
||||
}
|
||||
case Instruction::Add:
|
||||
default:
|
||||
cerr << "ConstantExpr not handled as global var init: " << *CE << "\n";
|
||||
@ -805,14 +828,16 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
|
||||
break;
|
||||
}
|
||||
case Type::PointerTyID:
|
||||
if (isa<ConstantPointerNull>(C))
|
||||
if (isa<ConstantPointerNull>(PC))
|
||||
memset(ptr, 0, TD->getPointerSize());
|
||||
else if (const GlobalValue* GV = dyn_cast<GlobalValue>(C))
|
||||
else if (const GlobalValue* GV = dyn_cast<GlobalValue>(PC)) {
|
||||
// FIXME: what about function stubs?
|
||||
MRs.push_back(MachineRelocation::getGV(PA-(intptr_t)Addr,
|
||||
MachineRelocation::VANILLA,
|
||||
const_cast<GlobalValue*>(GV)));
|
||||
else
|
||||
const_cast<GlobalValue*>(GV),
|
||||
ScatteredOffset));
|
||||
ScatteredOffset = 0;
|
||||
} else
|
||||
assert(0 && "Unknown constant pointer type!");
|
||||
break;
|
||||
default:
|
||||
@ -853,10 +878,10 @@ MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
|
||||
assert(!isa<Function>(gv) && "Unexpected linkage type for Function!");
|
||||
case GlobalValue::ExternalLinkage:
|
||||
GVName = TAI->getGlobalPrefix() + name;
|
||||
n_type |= N_EXT;
|
||||
n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT;
|
||||
break;
|
||||
case GlobalValue::InternalLinkage:
|
||||
GVName = TAI->getPrivateGlobalPrefix() + name;
|
||||
GVName = TAI->getGlobalPrefix() + name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace {
|
||||
: MachOWriter(O, TM) {}
|
||||
|
||||
virtual void GetTargetRelocation(MachineRelocation &MR, MachOSection &From,
|
||||
MachOSection &To);
|
||||
MachOSection &To, bool Scattered);
|
||||
|
||||
// Constants for the relocation r_type field.
|
||||
// see <mach-o/ppc/reloc.h>
|
||||
@ -59,7 +59,8 @@ void llvm::addPPCMachOObjectWriterPass(FunctionPassManager &FPM,
|
||||
/// by that relocation type.
|
||||
void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR,
|
||||
MachOSection &From,
|
||||
MachOSection &To) {
|
||||
MachOSection &To,
|
||||
bool Scattered) {
|
||||
uint64_t Addr = 0;
|
||||
|
||||
// Keep track of whether or not this is an externally defined relocation.
|
||||
@ -77,18 +78,30 @@ void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR,
|
||||
case PPC::reloc_vanilla:
|
||||
{
|
||||
// FIXME: need to handle 64 bit vanilla relocs
|
||||
MachORelocation VANILLA(MR.getMachineCodeOffset(), To.Index, false, 2,
|
||||
isExtern, PPC_RELOC_VANILLA);
|
||||
MachORelocation VANILLA(MR.getMachineCodeOffset(), To.Index, false, 2,
|
||||
isExtern, PPC_RELOC_VANILLA, Scattered,
|
||||
(intptr_t)MR.getResultPointer());
|
||||
++From.nreloc;
|
||||
|
||||
OutputBuffer RelocOut(From.RelocBuffer, is64Bit, isLittleEndian);
|
||||
RelocOut.outword(VANILLA.r_address);
|
||||
RelocOut.outword(VANILLA.getPackedFields());
|
||||
|
||||
OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian);
|
||||
SecOut.fixword(Addr, MR.getMachineCodeOffset());
|
||||
break;
|
||||
|
||||
if (Scattered) {
|
||||
RelocOut.outword(VANILLA.getPackedFields());
|
||||
RelocOut.outword(VANILLA.getAddress());
|
||||
} else {
|
||||
RelocOut.outword(VANILLA.getAddress());
|
||||
RelocOut.outword(VANILLA.getPackedFields());
|
||||
}
|
||||
|
||||
intptr_t SymbolOffset;
|
||||
if (Scattered)
|
||||
SymbolOffset = Addr + MR.getConstantVal();
|
||||
else
|
||||
SymbolOffset = Addr;
|
||||
printf("vanilla fixup: sec_%x[%x] = %x\n", From.Index, unsigned(MR.getMachineCodeOffset()), (unsigned)SymbolOffset);
|
||||
SecOut.fixword(SymbolOffset, MR.getMachineCodeOffset());
|
||||
}
|
||||
break;
|
||||
case PPC::reloc_pcrel_bx:
|
||||
{
|
||||
Addr -= MR.getMachineCodeOffset();
|
||||
@ -124,7 +137,6 @@ void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR,
|
||||
RelocOut.outword(HA16.getPackedFields());
|
||||
RelocOut.outword(PAIR.r_address);
|
||||
RelocOut.outword(PAIR.getPackedFields());
|
||||
printf("ha16: %x\n", (unsigned)Addr);
|
||||
Addr += 0x8000;
|
||||
|
||||
OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian);
|
||||
@ -145,7 +157,6 @@ void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR,
|
||||
RelocOut.outword(LO16.getPackedFields());
|
||||
RelocOut.outword(PAIR.r_address);
|
||||
RelocOut.outword(PAIR.getPackedFields());
|
||||
printf("lo16: %x\n", (unsigned)Addr);
|
||||
|
||||
OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian);
|
||||
SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);
|
||||
|
Loading…
Reference in New Issue
Block a user