DataRefImpl d;
d.p = getAddend<ELFT>(rel);
return RelocAddrEntry{secIndex, RelocationRef(d, nullptr),
- LLDRelocationResolver<RelTy>::resolve, val};
+ val, Optional<object::RelocationRef>(),
+ 0, LLDRelocationResolver<RelTy>::resolve};
}
template <class ELFT>
struct RelocAddrEntry {
uint64_t SectionIndex;
object::RelocationRef Reloc;
- object::RelocationResolver Resolver;
uint64_t SymbolValue;
+ Optional<object::RelocationRef> Reloc2;
+ uint64_t SymbolValue2;
+ object::RelocationResolver Resolver;
};
/// In place of applying the relocations to the data we've read from disk we use
//
// TODO Don't store Resolver in every RelocAddrEntry.
if (Supports && Supports(Reloc.getType())) {
- Map->try_emplace(Reloc.getOffset(),
- RelocAddrEntry{SymInfoOrErr->SectionIndex, Reloc,
- Resolver, SymInfoOrErr->Address});
+ auto I = Map->try_emplace(
+ Reloc.getOffset(),
+ RelocAddrEntry{SymInfoOrErr->SectionIndex, Reloc,
+ SymInfoOrErr->Address,
+ Optional<object::RelocationRef>(), 0, Resolver});
+ // If we didn't successfully insert that's because we already had a
+ // relocation for that offset. Store it as a second relocation in the
+ // same RelocAddrEntry instead.
+ if (!I.second) {
+ RelocAddrEntry &entry = I.first->getSecond();
+ if (entry.Reloc2) {
+ ErrorPolicy EP = HandleError(createError(
+ "At most two relocations per offset are supported"));
+ if (EP == ErrorPolicy::Halt)
+ return;
+ }
+ entry.Reloc2 = Reloc;
+ entry.SymbolValue2 = SymInfoOrErr->Address;
+ }
} else {
SmallString<32> Type;
Reloc.getTypeName(Type);
return A;
if (SecNdx)
*SecNdx = E->SectionIndex;
- return E->Resolver(E->Reloc, E->SymbolValue, A);
+ uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A);
+ if (E->Reloc2)
+ R = E->Resolver(*E->Reloc2, E->SymbolValue2, R);
+ return R;
}
Optional<uint64_t>
const uint64_t PrologueOffset = *OffsetPtr;
clear();
- TotalLength = DebugLineData.getU32(OffsetPtr);
+ TotalLength = DebugLineData.getRelocatedValue(4, OffsetPtr);
if (TotalLength == UINT32_MAX) {
FormParams.Format = dwarf::DWARF64;
TotalLength = DebugLineData.getU64(OffsetPtr);
SegSelectorSize = DebugLineData.getU8(OffsetPtr);
}
- PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
+ PrologueLength =
+ DebugLineData.getRelocatedValue(sizeofPrologueLength(), OffsetPtr);
const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
MinInstLength = DebugLineData.getU8(OffsetPtr);
if (getVersion() >= 4)
// requires the use of DW_LNS_advance_pc. Such assemblers, however,
// can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
{
- uint16_t PCOffset = DebugLineData.getU16(OffsetPtr);
+ uint16_t PCOffset = DebugLineData.getRelocatedValue(2, OffsetPtr);
State.Row.Address.Address += PCOffset;
if (OS)
*OS
case DW_FORM_data8:
case DW_FORM_ref8:
case DW_FORM_ref_sup8:
- Value.uval = Data.getU64(OffsetPtr);
+ Value.uval = Data.getRelocatedValue(8, OffsetPtr);
break;
case DW_FORM_data16:
// Treat this like a 16-byte block.
"%s table length at offset 0x%" PRIx32,
SectionName.data(), *OffsetPtr);
// TODO: Add support for DWARF64.
- HeaderData.Length = Data.getU32(OffsetPtr);
+ HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
if (HeaderData.Length == 0xffffffffu)
return createStringError(errc::not_supported,
"DWARF64 is not supported in %s at offset 0x%" PRIx32,
SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
Data.setAddressSize(HeaderData.AddrSize);
for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
- Offsets.push_back(Data.getU32(OffsetPtr));
+ Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr));
return Error::success();
}
IndexEntry = Entry;
if (!IndexEntry && Index)
IndexEntry = Index->getFromOffset(*offset_ptr);
- Length = debug_info.getU32(offset_ptr);
+ Length = debug_info.getRelocatedValue(4, offset_ptr);
FormParams.Format = DWARF32;
unsigned SizeOfLength = 4;
if (Length == 0xffffffff) {
llvm_unreachable("Invalid relocation type");
}
+static bool supportsRISCV(uint64_t Type) {
+ switch (Type) {
+ case ELF::R_RISCV_NONE:
+ case ELF::R_RISCV_32:
+ case ELF::R_RISCV_64:
+ case ELF::R_RISCV_ADD8:
+ case ELF::R_RISCV_SUB8:
+ case ELF::R_RISCV_ADD16:
+ case ELF::R_RISCV_SUB16:
+ case ELF::R_RISCV_ADD32:
+ case ELF::R_RISCV_SUB32:
+ case ELF::R_RISCV_ADD64:
+ case ELF::R_RISCV_SUB64:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) {
+ int64_t RA = getELFAddend(R);
+ switch (R.getType()) {
+ case ELF::R_RISCV_NONE:
+ return A;
+ case ELF::R_RISCV_32:
+ return (S + RA) & 0xFFFFFFFF;
+ case ELF::R_RISCV_64:
+ return S + RA;
+ case ELF::R_RISCV_ADD8:
+ return (A + (S + RA)) & 0xFF;
+ case ELF::R_RISCV_SUB8:
+ return (A - (S + RA)) & 0xFF;
+ case ELF::R_RISCV_ADD16:
+ return (A + (S + RA)) & 0xFFFF;
+ case ELF::R_RISCV_SUB16:
+ return (A - (S + RA)) & 0xFFFF;
+ case ELF::R_RISCV_ADD32:
+ return (A + (S + RA)) & 0xFFFFFFFF;
+ case ELF::R_RISCV_SUB32:
+ return (A - (S + RA)) & 0xFFFFFFFF;
+ case ELF::R_RISCV_ADD64:
+ return (A + (S + RA));
+ case ELF::R_RISCV_SUB64:
+ return (A - (S + RA));
+ default:
+ llvm_unreachable("Invalid relocation type");
+ }
+}
+
static bool supportsCOFFX86(uint64_t Type) {
switch (Type) {
case COFF::IMAGE_REL_I386_SECREL:
return {supportsSparc64, resolveSparc64};
case Triple::amdgcn:
return {supportsAmdgpu, resolveAmdgpu};
+ case Triple::riscv64:
+ return {supportsRISCV, resolveRISCV};
default:
return {nullptr, nullptr};
}
return {supportsSparc32, resolveSparc32};
case Triple::hexagon:
return {supportsHexagon, resolveHexagon};
+ case Triple::riscv32:
+ return {supportsRISCV, resolveRISCV};
default:
return {nullptr, nullptr};
}
--- /dev/null
+; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=+relax %s -o %t.o
+; RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=READOBJ-RELOCS %s
+; RUN: llvm-objdump --source %t.o | FileCheck -check-prefix=OBJDUMP-SOURCE %s
+; RUN: llvm-dwarfdump --debug-info --debug-line %t.o | \
+; RUN: FileCheck -check-prefix=DWARF-DUMP %s
+
+; Check that we actually have relocations, otherwise this is kind of pointless.
+; READOBJ-RELOCS: Section (8) .rela.debug_info {
+; READOBJ-RELOCS-NEXT: 0x0 R_RISCV_ADD32 - 0x0
+; READOBJ-RELOCS-NEXT: 0x0 R_RISCV_SUB32 - 0x0
+; READOBJ-RELOCS: Section (11) .rela.debug_addr {
+; READOBJ-RELOCS-NEXT: 0x0 R_RISCV_ADD32 - 0x0
+; READOBJ-RELOCS-NEXT: 0x0 R_RISCV_SUB32 - 0x0
+; READOBJ-RELOCS: Section (17) .rela.debug_line {
+; READOBJ-RELOCS-NEXT: 0x0 R_RISCV_ADD32 - 0xFFFFFFFC
+; READOBJ-RELOCS-NEXT: 0x0 R_RISCV_SUB32 .Lline_table_start0 0x0
+
+; Check that we can print the source, even with relocations.
+; OBJDUMP-SOURCE: Disassembly of section .text:
+; OBJDUMP-SOURCE-EMPTY:
+; OBJDUMP-SOURCE-NEXT: 00000000 main:
+; OBJDUMP-SOURCE: ; {
+; OBJDUMP-SOURCE: ; return 0;
+
+; Check that we correctly dump the DWARF info, even with relocations.
+; DWARF-DUMP: DW_AT_name ("dwarf-riscv-relocs.c")
+; DWARF-DUMP: DW_AT_comp_dir (".")
+; DWARF-DUMP: DW_AT_name ("main")
+; DWARF-DUMP: DW_AT_decl_file ("./dwarf-riscv-relocs.c")
+; DWARF-DUMP: DW_AT_decl_line (1)
+; DWARF-DUMP: DW_AT_type (0x00000032 "int")
+; DWARF-DUMP: DW_AT_name ("int")
+; DWARF-DUMP: DW_AT_encoding (DW_ATE_signed)
+; DWARF-DUMP: DW_AT_byte_size (0x04)
+
+; DWARF-DUMP: .debug_line contents:
+; DWARF-DUMP-NEXT: debug_line[0x00000000]
+; DWARF-DUMP-NEXT: Line table prologue:
+; DWARF-DUMP-NEXT: total_length: 0x0000005f
+; DWARF-DUMP-NEXT: version: 5
+; DWARF-DUMP-NEXT: address_size: 4
+; DWARF-DUMP-NEXT: seg_select_size: 0
+; DWARF-DUMP-NEXT: prologue_length: 0x0000003e
+; DWARF-DUMP-NEXT: min_inst_length: 1
+; DWARF-DUMP-NEXT: max_ops_per_inst: 1
+; DWARF-DUMP-NEXT: default_is_stmt: 1
+; DWARF-DUMP-NEXT: line_base: -5
+; DWARF-DUMP-NEXT: line_range: 14
+; DWARF-DUMP-NEXT: opcode_base: 13
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_copy] = 0
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_advance_pc] = 1
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_advance_line] = 1
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_set_file] = 1
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_set_column] = 1
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_negate_stmt] = 0
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_set_basic_block] = 0
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_const_add_pc] = 0
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0
+; DWARF-DUMP-NEXT: standard_opcode_lengths[DW_LNS_set_isa] = 1
+; DWARF-DUMP-NEXT: include_directories[ 0] = "."
+; DWARF-DUMP-NEXT: file_names[ 0]:
+; DWARF-DUMP-NEXT: name: "dwarf-riscv-relocs.c"
+; DWARF-DUMP-NEXT: dir_index: 0
+; DWARF-DUMP-NEXT: md5_checksum: 05ab89f5481bc9f2d037e7886641e919
+; DWARF-DUMP-NEXT: source: "int main()\n{\n return 0;\n}\n"
+; DWARF-DUMP-EMPTY:
+; DWARF-DUMP-NEXT: Address Line Column File ISA Discriminator Flags
+; DWARF-DUMP-NEXT: ------------------ ------ ------ ------ --- ------------- -------------
+; DWARF-DUMP-NEXT: 0x0000000000000000 2 0 0 0 0 is_stmt
+; DWARF-DUMP-NEXT: 0x0000000000000014 3 5 0 0 0 is_stmt prologue_end
+; DWARF-DUMP-NEXT: 0x0000000000000028 3 5 0 0 0 is_stmt end_sequence
+
+; ModuleID = 'dwarf-riscv-relocs.c'
+source_filename = "dwarf-riscv-relocs.c"
+target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
+target triple = "riscv32"
+
+; Function Attrs: noinline nounwind optnone
+define dso_local i32 @main() #0 !dbg !7 {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, i32* %retval, align 4
+ ret i32 0, !dbg !11
+}
+
+attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+relax" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "dwarf-riscv-relocs.c", directory: ".", checksumkind: CSK_MD5, checksum: "05ab89f5481bc9f2d037e7886641e919", source: "int main()\0A{\0A return 0;\0A}\0A")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang"}
+!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !8, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !DILocation(line: 3, column: 5, scope: !7)