Commit 261cae38 by Jan Voung

Track undefined sym in the symtab. Remove hack for missing relocs against undef.

Preliminary linking tests, seems to show that the linker and objcopy are happy to use 'em on spec2k, and the result runs! (Had to be careful to clobber the old .s and .o files to make it's testing the right copy). Haven't tried crosstests yet. BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/889613004
parent 046ec2e0
......@@ -532,12 +532,23 @@ void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) {
writeRelocationSections(IsELF64, RelRODataSections);
}
void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) {
for (const Constant *S : UndefSyms) {
const auto Sym = llvm::cast<ConstantRelocatable>(S);
IceString Name = Sym->getName();
assert(Sym->getOffset() == 0);
assert(Sym->getSuppressMangling());
SymTab->noteUndefinedSym(Name, NullSection);
StrTab->add(Name);
}
}
void ELFObjectWriter::writeRelocationSections(bool IsELF64,
RelSectionList &RelSections) {
for (ELFRelocationSection *RelSec : RelSections) {
Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign());
RelSec->setFileOffset(Offset);
RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab));
RelSec->setSize(RelSec->getSectionDataSize());
if (IsELF64) {
RelSec->writeData<true>(Ctx, Str, SymTab);
} else {
......
......@@ -33,7 +33,8 @@ namespace Ice {
// (2) writeDataSection (invoke once)
// (3) writeFunctionCode (must invoke once per function)
// (4) writeConstantPool (must invoke once per pooled primitive type)
// (5) writeNonUserSections (invoke once)
// (5) setUndefinedSyms (invoke once)
// (6) writeNonUserSections (invoke once)
//
// The requirement for writeDataSection to be invoked only once can
// be relaxed if using -fdata-sections. The requirement to invoke only once
......@@ -76,6 +77,9 @@ public:
// fills the symbol table with labels for each constant pool entry.
template <typename ConstType> void writeConstantPool(Type Ty);
// Populate the symbol table with a list of external/undefined symbols.
void setUndefinedSyms(const ConstantList &UndefSyms);
// Do final layout and write out the rest of the object file.
// Finally, patch up the initial ELF header with the final info.
void writeNonUserSections();
......
......@@ -74,18 +74,8 @@ void ELFRelocationSection::addRelocations(RelocOffsetT BaseOff,
}
}
size_t ELFRelocationSection::getSectionDataSize(
const GlobalContext &Ctx, const ELFSymbolTableSection *SymTab) const {
size_t NumWriteableRelocs = 0;
for (const AssemblerFixup &Fixup : Fixups) {
const ELFSym *Symbol = SymTab->findSymbol(Fixup.symbol(&Ctx));
// TODO(jvoung): When the symbol table finally tracks everything,
// just use the Fixups.size() as the count, and remove the
// SymTab and Ctx params.
if (Symbol)
++NumWriteableRelocs;
}
return NumWriteableRelocs * Header.sh_entsize;
size_t ELFRelocationSection::getSectionDataSize() const {
return Fixups.size() * Header.sh_entsize;
}
// Symbol tables.
......
......@@ -217,8 +217,7 @@ public:
// Track a single additional relocation.
void addRelocation(const AssemblerFixup &Fixup) { Fixups.push_back(Fixup); }
size_t getSectionDataSize(const GlobalContext &Ctx,
const ELFSymbolTableSection *SymTab) const;
size_t getSectionDataSize() const;
template <bool IsELF64>
void writeData(const GlobalContext &Ctx, ELFStreamer &Str,
......@@ -333,25 +332,23 @@ void ELFRelocationSection::writeData(const GlobalContext &Ctx, ELFStreamer &Str,
const ELFSymbolTableSection *SymTab) {
for (const AssemblerFixup &Fixup : Fixups) {
const ELFSym *Symbol = SymTab->findSymbol(Fixup.symbol(&Ctx));
// TODO(jvoung): Make sure this always succeeds.
// We currently don't track data symbols, so they aren't even marked
// as undefined symbols.
if (Symbol) {
if (IsELF64) {
Elf64_Rela Rela;
Rela.r_offset = Fixup.position();
Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
Rela.r_addend = Fixup.offset();
Str.writeAddrOrOffset<IsELF64>(Rela.r_offset);
Str.writeELFXword<IsELF64>(Rela.r_info);
Str.writeELFXword<IsELF64>(Rela.r_addend);
} else {
Elf32_Rel Rel;
Rel.r_offset = Fixup.position();
Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
Str.writeAddrOrOffset<IsELF64>(Rel.r_offset);
Str.writeELFWord<IsELF64>(Rel.r_info);
}
if (!Symbol)
llvm::report_fatal_error("Missing symbol mentioned in reloc");
if (IsELF64) {
Elf64_Rela Rela;
Rela.r_offset = Fixup.position();
Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
Rela.r_addend = Fixup.offset();
Str.writeAddrOrOffset<IsELF64>(Rela.r_offset);
Str.writeELFXword<IsELF64>(Rela.r_info);
Str.writeELFXword<IsELF64>(Rela.r_addend);
} else {
Elf32_Rel Rel;
Rel.r_offset = Fixup.position();
Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
Str.writeAddrOrOffset<IsELF64>(Rel.r_offset);
Str.writeELFWord<IsELF64>(Rel.r_info);
}
}
}
......
......@@ -105,6 +105,8 @@ public:
TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32;
TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64;
TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables;
TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable>
ExternRelocatables;
UndefPool Undefs;
};
......@@ -422,6 +424,13 @@ Constant *GlobalContext::getConstantSym(RelocOffsetT Offset,
this, RelocatableTuple(Offset, Name, SuppressMangling));
}
Constant *GlobalContext::getConstantExternSym(const IceString &Name) {
const RelocOffsetT Offset = 0;
const bool SuppressMangling = true;
return getConstPool()->ExternRelocatables.getOrAdd(
this, RelocatableTuple(Offset, Name, SuppressMangling));
}
Constant *GlobalContext::getConstantUndef(Type Ty) {
return getConstPool()->Undefs.getOrAdd(this, Ty);
}
......@@ -494,6 +503,10 @@ ConstantList GlobalContext::getConstantPool(Type Ty) {
llvm_unreachable("Unknown type");
}
ConstantList GlobalContext::getConstantExternSyms() {
return getConstPool()->ExternRelocatables.getConstantPool();
}
TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) {
if (!ALLOW_DUMP)
return 0;
......
......@@ -188,6 +188,7 @@ public:
// Returns a symbolic constant.
Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name,
bool SuppressMangling);
Constant *getConstantExternSym(const IceString &Name);
// Returns an undef.
Constant *getConstantUndef(Type Ty);
// Returns a zero value.
......@@ -195,6 +196,8 @@ public:
// getConstantPool() returns a copy of the constant pool for
// constants of a given type.
ConstantList getConstantPool(Type Ty);
// Returns a copy of the list of external symbols.
ConstantList getConstantExternSyms();
const ClFlags &getFlags() const { return Flags; }
......
......@@ -153,12 +153,11 @@ protected:
OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty);
Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
// Make a call to an external helper function.
InstCall *makeHelperCall(const IceString &Name, Variable *Dest,
SizeT MaxSrcs) {
const bool SuppressMangling = true;
const bool HasTailCall = false;
const RelocOffsetT Offset = 0;
Constant *CallTarget = Ctx->getConstantSym(Offset, Name, SuppressMangling);
Constant *CallTarget = Ctx->getConstantExternSym(Name);
InstCall *Call =
InstCall::create(Func, MaxSrcs, Dest, CallTarget, HasTailCall);
return Call;
......
......@@ -398,6 +398,7 @@ int main(int argc, char **argv) {
if (UseELFWriter) {
Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx);
Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms());
Ctx.getObjectWriter()->writeNonUserSections();
}
if (SubzeroTimingEnabled)
......
......@@ -385,12 +385,8 @@ define void @_start(i32) {
; CHECK: 0x24 R_386_32 .L$double$0 0x0
; CHECK: 0x2C R_386_32 .L$double$1 0x0
; CHECK: 0x34 R_386_32 .L$double$2 0x0
; The set of relocations between llvm-mc and integrated elf-writer
; are different. The integrated elf-writer does not yet handle
; external/undef functions like memcpy. Also, it does not resolve internal
; function calls and instead writes out the relocation. However, there's
; probably some function call so check for a PC32 relocation at least.
; CHECK: 0x{{.*}} R_386_PC32
; CHECK: 0x{{.*}} R_386_PC32 memcpy
; CHECK: 0x{{.*}} R_386_PC32 memset
; CHECK: }
; CHECK: Section ({{[0-9]+}}) .rel.data {
; The set of relocations between llvm-mc and the integrated elf-writer
......@@ -617,4 +613,22 @@ define void @_start(i32) {
; CHECK-NEXT: Other: 0
; CHECK-NEXT: Section: .text
; CHECK-NEXT: }
; CHECK: Symbol {
; CHECK: Name: memcpy
; CHECK-NEXT: Value: 0x0
; CHECK-NEXT: Size: 0
; CHECK-NEXT: Binding: Global
; CHECK-NEXT: Type: None
; CHECK-NEXT: Other: 0
; CHECK-NEXT: Section: Undefined
; CHECK-NEXT: }
; CHECK: Symbol {
; CHECK: Name: memset
; CHECK-NEXT: Value: 0x0
; CHECK-NEXT: Size: 0
; CHECK-NEXT: Binding: Global
; CHECK-NEXT: Type: None
; CHECK-NEXT: Other: 0
; CHECK-NEXT: Section: Undefined
; CHECK-NEXT: }
; CHECK: ]
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