Index: lld/trunk/ELF/DWARF.cpp
===================================================================
--- lld/trunk/ELF/DWARF.cpp
+++ lld/trunk/ELF/DWARF.cpp
@@ -110,7 +110,8 @@
   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>
Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
@@ -20,8 +20,10 @@
 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
Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1651,9 +1651,25 @@
         //
         // 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);
Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -24,7 +24,10 @@
     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>
Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -300,7 +300,7 @@
   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);
@@ -325,7 +325,8 @@
     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)
@@ -754,7 +755,7 @@
         // 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
Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -299,7 +299,7 @@
     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.
Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -25,7 +25,7 @@
                        "%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,
@@ -73,7 +73,7 @@
         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();
 }
 
Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -241,7 +241,7 @@
   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) {
Index: llvm/trunk/lib/Object/RelocationResolver.cpp
===================================================================
--- llvm/trunk/lib/Object/RelocationResolver.cpp
+++ llvm/trunk/lib/Object/RelocationResolver.cpp
@@ -330,6 +330,55 @@
   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:
@@ -449,6 +498,8 @@
         return {supportsSparc64, resolveSparc64};
       case Triple::amdgcn:
         return {supportsAmdgpu, resolveAmdgpu};
+      case Triple::riscv64:
+        return {supportsRISCV, resolveRISCV};
       default:
         return {nullptr, nullptr};
       }
@@ -477,6 +528,8 @@
       return {supportsSparc32, resolveSparc32};
     case Triple::hexagon:
       return {supportsHexagon, resolveHexagon};
+    case Triple::riscv32:
+      return {supportsRISCV, resolveRISCV};
     default:
       return {nullptr, nullptr};
     }
Index: llvm/trunk/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
===================================================================
--- llvm/trunk/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
+++ llvm/trunk/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
@@ -0,0 +1,105 @@
+; 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)