Index: src/cmd/link/internal/loadelf/ldelf.go
--- src/cmd/link/internal/loadelf/ldelf.go.orig
+++ src/cmd/link/internal/loadelf/ldelf.go
@@ -583,27 +583,41 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVe
 		}
 		sect = &elfobj.sect[elfsym.shndx]
 		if sect.sym == 0 {
-			if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this
-				continue
-			}
+			if elfsym.type_ == 0 {
+				if strings.HasPrefix(sect.name, ".debug_") && elfsym.name == "" {
+					// clang on arm and riscv64.
+					// This reportedly happens with clang 3.7 on ARM.
+					// See issue 13139.
+					continue
+				}
+				if strings.HasPrefix(elfsym.name, ".Ldebug_") || elfsym.name == ".L0 " {
+					// gcc on riscv64.
+					continue
+				}
+				if elfsym.name == ".Lline_table_start0" {
+					// clang on riscv64.
+					continue
+				}
 
-			if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" {
-				// This reportedly happens with clang 3.7 on ARM.
-				// See issue 13139.
-				continue
+				if strings.HasPrefix(elfsym.name, "$d") && sect.name == ".debug_frame" {
+					// "$d" is a marker, not a real symbol.
+					// This happens with gcc on ARM64.
+					// See https://sourceware.org/bugzilla/show_bug.cgi?id=21809
+					continue
+				}
 			}
 
-			if strings.HasPrefix(elfsym.name, "$d") && elfsym.type_ == 0 && sect.name == ".debug_frame" {
-				// "$d" is a marker, not a real symbol.
-				// This happens with gcc on ARM64.
-				// See https://sourceware.org/bugzilla/show_bug.cgi?id=21809
+			if strings.HasPrefix(elfsym.name, ".Linfo_string") {
+				// clang does this
 				continue
 			}
 
-			if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this
+			if strings.HasPrefix(elfsym.name, ".LASF") || strings.HasPrefix(elfsym.name, ".LLST") {
+				// gcc on s390x and riscv64 does this.
 				continue
 			}
-			return errorf("%v: sym#%d (%s): ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.name, elfsym.shndx, elfsym.type_)
+
+			return errorf("%v: sym#%d (%q): ignoring symbol in section %d (%q) (type %d)", elfsym.sym, i, elfsym.name, elfsym.shndx, sect.name, elfsym.type_)
 		}
 
 		s := elfsym.sym
@@ -1079,8 +1093,16 @@ func relSize(arch *sys.Arch, pn string, elftype uint32
 		S390X | uint32(elf.R_390_PLT64)<<16:
 		return 8, 8, nil
 
+	case RISCV64 | uint32(elf.R_RISCV_SET6)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB6)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SET8)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB8)<<16:
+		return 1, 1, nil
+
 	case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
-		RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16:
+		RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SET16)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB16)<<16:
 		return 2, 2, nil
 
 	case RISCV64 | uint32(elf.R_RISCV_32)<<16,
@@ -1092,6 +1114,10 @@ func relSize(arch *sys.Arch, pn string, elftype uint32
 		RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16,
 		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
 		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
+		RISCV64 | uint32(elf.R_RISCV_ADD32)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SET32)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB32)<<16,
+		RISCV64 | uint32(elf.R_RISCV_32_PCREL)<<16,
 		RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
 		return 4, 4, nil
 
